{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Coding: Language Model based on LSTM\n",
    "\n",
    " - Dataset: WikiText-2\n",
    " - Model: LSTM/GRU\n",
    " - Optimizer: Adam\n",
    " - Learning Rate: 0.0001\n",
    " - Batch Size: 64\n",
    " - Epochs: 10\n",
    " - Dropout: 0.2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/home/archer/archer/lib/python3.12/site-packages/tqdm/auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n",
      "  from .autonotebook import tqdm as notebook_tqdm\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Using device: cpu\n",
      "Loading WikiText-2 dataset from Hugging Face...\n",
      "Train dataset size: 36718\n",
      "Validation dataset size: 3760\n",
      "Test dataset size: 4358\n",
      "\n",
      "Looking for non-empty samples...\n",
      "Found non-empty sample at index 1\n",
      "First sample:  = Valkyria Chronicles III = \n",
      "\n",
      "\n",
      "Building vocabulary...\n",
      "Non-empty lines: 23767\n",
      "Total tokens: 1750345\n",
      "Vocabulary size: 28710\n",
      "Final vocabulary size (with special tokens): 28712\n",
      "Most common words: [('the', 130768), ('of', 57030), ('unk', 54625), ('and', 50735), ('in', 45015), ('to', 39521), ('a', 36523), ('was', 21008), ('on', 15140), ('as', 15058)]\n",
      "\n",
      "Sample tokenization:\n",
      "Original:  = Valkyria Chronicles III = \n",
      "\n",
      "Tokens: ['valkyria', 'chronicles', 'iii']\n",
      "Indices: [3767, 3830, 860]\n",
      "\n",
      "Dataset loaded successfully!\n"
     ]
    }
   ],
   "source": [
    "# Load WikiText-2 Dataset using Hugging Face datasets\n",
    "\n",
    "import torch\n",
    "from datasets import load_dataset\n",
    "from torch.utils.data import DataLoader\n",
    "from collections import Counter\n",
    "import re\n",
    "\n",
    "# Set device\n",
    "device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')\n",
    "print(f'Using device: {device}')\n",
    "\n",
    "# Load WikiText-2 dataset from Hugging Face\n",
    "print(\"Loading WikiText-2 dataset from Hugging Face...\")\n",
    "dataset = load_dataset(\"wikitext\", \"wikitext-2-v1\")\n",
    "\n",
    "# Access the splits\n",
    "train_dataset = dataset['train']\n",
    "val_dataset = dataset['validation']\n",
    "test_dataset = dataset['test']\n",
    "\n",
    "print(f\"Train dataset size: {len(train_dataset)}\")\n",
    "print(f\"Validation dataset size: {len(val_dataset)}\")\n",
    "print(f\"Test dataset size: {len(test_dataset)}\")\n",
    "\n",
    "# Show a sample\n",
    "# Find a non-empty sample\n",
    "print(f\"\\nLooking for non-empty samples...\")\n",
    "sample_text = None\n",
    "for i, example in enumerate(train_dataset):\n",
    "    if example['text'].strip():  # Find first non-empty line\n",
    "        sample_text = example['text']\n",
    "        print(f\"Found non-empty sample at index {i}\")\n",
    "        break\n",
    "print(f\"First sample: {sample_text[:200]}\")\n",
    "\n",
    "# Basic tokenization function\n",
    "def basic_tokenize(text):\n",
    "    # Convert to lowercase and split on whitespace and punctuation\n",
    "    text = text.lower()\n",
    "    tokens = re.findall(r'\\b\\w+\\b', text)\n",
    "    return tokens\n",
    "\n",
    "# Build vocabulary from training data\n",
    "print(\"\\nBuilding vocabulary...\")\n",
    "all_tokens = []\n",
    "non_empty_lines = 0\n",
    "for example in train_dataset:\n",
    "    if example['text'].strip():  # Skip empty lines\n",
    "        tokens = basic_tokenize(example['text'])\n",
    "        all_tokens.extend(tokens)\n",
    "        non_empty_lines += 1\n",
    "\n",
    "# Create vocabulary\n",
    "vocab_counter = Counter(all_tokens)\n",
    "vocab_size = len(vocab_counter)\n",
    "print(f\"Non-empty lines: {non_empty_lines}\")\n",
    "print(f\"Total tokens: {len(all_tokens)}\")\n",
    "print(f\"Vocabulary size: {vocab_size}\")\n",
    "\n",
    "# Create word to index mapping\n",
    "vocab = {'<unk>': 0, '<pad>': 1}\n",
    "for word, count in vocab_counter.most_common():\n",
    "    if word not in vocab:\n",
    "        vocab[word] = len(vocab)\n",
    "\n",
    "# Create index to word mapping\n",
    "idx_to_word = {idx: word for word, idx in vocab.items()}\n",
    "\n",
    "print(f\"Final vocabulary size (with special tokens): {len(vocab)}\")\n",
    "print(f\"Most common words: {list(vocab_counter.most_common(10))}\")\n",
    "\n",
    "# Function to convert text to indices\n",
    "def text_to_indices(text, vocab):\n",
    "    tokens = basic_tokenize(text)\n",
    "    return [vocab.get(token, vocab['<unk>']) for token in tokens]\n",
    "\n",
    "# Convert a sample to see the tokenization\n",
    "sample_indices = text_to_indices(sample_text, vocab)\n",
    "print(f\"\\nSample tokenization:\")\n",
    "print(f\"Original: {sample_text[:100]}\")\n",
    "print(f\"Tokens: {basic_tokenize(sample_text)[:20]}\")\n",
    "print(f\"Indices: {sample_indices[:20]}\")\n",
    "\n",
    "print(\"\\nDataset loaded successfully!\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Creating training dataset...\n",
      "Processing dataset with sequence length: 50\n",
      "Total tokens in dataset: 1750345\n",
      "Created 1750295 sequences\n",
      "\n",
      "Creating validation dataset...\n",
      "Processing dataset with sequence length: 50\n",
      "Total tokens in dataset: 183606\n",
      "Created 183556 sequences\n",
      "\n",
      "Creating test dataset...\n",
      "Processing dataset with sequence length: 50\n",
      "Total tokens in dataset: 206381\n",
      "Created 206331 sequences\n",
      "\n",
      "DataLoader Summary:\n",
      "Training batches: 27349\n",
      "Validation batches: 2869\n",
      "Test batches: 3224\n",
      "Batch size: 64\n",
      "Sequence length: 50\n",
      "\n",
      "Testing DataLoader...\n",
      "Batch 1:\n",
      "  Sequences shape: torch.Size([64, 50])\n",
      "  Targets shape: torch.Size([64])\n",
      "  Sample sequence: [2, 2232, 946, 2448, 10, 2, 3605, 2212, 15, 36]\n",
      "  Sample target: 6737\n",
      "  Sample words: ['the', 'fur', 'trade', 'focused', 'on', 'the', 'continental', 'interior', 'with', 'its', 'unk', 'rivers', 'and', 'lakes', 'the', 'cod', 'fisheries', 'looks', 'outward', 'at', 'global', 'trade', 'and', 'empire', 'showing', 'the', 'far', 'reaching', 'effects', 'of', 'one', 'staple', 'product', 'both', 'on', 'imperial', 'centres', 'and', 'on', 'marginal', 'colonies', 'such', 'as', 'newfoundland', 'nova', 'scotia', 'and', 'new', 'england', 'communications']\n",
      "  Target word: theories\n",
      "\n",
      "DataLoader created successfully!\n"
     ]
    }
   ],
   "source": [
    "# Data Preprocess & Init DataLoader\n",
    "\n",
    "import torch\n",
    "from torch.utils.data import Dataset, DataLoader\n",
    "import torch.nn.functional as F\n",
    "\n",
    "class WikiTextDataset(Dataset):\n",
    "    def __init__(self, hf_dataset, vocab, sequence_length=50):\n",
    "        \"\"\"\n",
    "        Custom Dataset for WikiText-2\n",
    "        \n",
    "        Args:\n",
    "            hf_dataset: Hugging Face dataset split\n",
    "            vocab: vocabulary dictionary\n",
    "            sequence_length: length of input sequences\n",
    "        \"\"\"\n",
    "        self.vocab = vocab\n",
    "        self.sequence_length = sequence_length\n",
    "        \n",
    "        # Process all text and create sequences\n",
    "        self.sequences = []\n",
    "        self.targets = []\n",
    "        \n",
    "        print(f\"Processing dataset with sequence length: {sequence_length}\")\n",
    "        \n",
    "        # Concatenate all non-empty text and tokenize\n",
    "        all_indices = []\n",
    "        for example in hf_dataset:\n",
    "            if example['text'].strip():  # Skip empty lines\n",
    "                indices = text_to_indices(example['text'], vocab)\n",
    "                all_indices.extend(indices)\n",
    "        \n",
    "        print(f\"Total tokens in dataset: {len(all_indices)}\")\n",
    "        \n",
    "        # Create sequences of specified length\n",
    "        for i in range(len(all_indices) - sequence_length):\n",
    "            # Input sequence\n",
    "            seq = all_indices[i:i + sequence_length]\n",
    "            # Target is the next token\n",
    "            target = all_indices[i + sequence_length]\n",
    "            \n",
    "            self.sequences.append(seq)\n",
    "            self.targets.append(target)\n",
    "        \n",
    "        print(f\"Created {len(self.sequences)} sequences\")\n",
    "    \n",
    "    def __len__(self):\n",
    "        return len(self.sequences)\n",
    "    \n",
    "    def __getitem__(self, idx):\n",
    "        return (\n",
    "            torch.tensor(self.sequences[idx], dtype=torch.long),\n",
    "            torch.tensor(self.targets[idx], dtype=torch.long)\n",
    "        )\n",
    "\n",
    "# Create datasets\n",
    "sequence_length = 50\n",
    "batch_size = 64\n",
    "\n",
    "print(\"Creating training dataset...\")\n",
    "train_wiki_dataset = WikiTextDataset(train_dataset, vocab, sequence_length)\n",
    "\n",
    "print(\"\\nCreating validation dataset...\")\n",
    "val_wiki_dataset = WikiTextDataset(val_dataset, vocab, sequence_length)\n",
    "\n",
    "print(\"\\nCreating test dataset...\")\n",
    "test_wiki_dataset = WikiTextDataset(test_dataset, vocab, sequence_length)\n",
    "\n",
    "# Create DataLoaders\n",
    "train_loader = DataLoader(\n",
    "    train_wiki_dataset, \n",
    "    batch_size=batch_size, \n",
    "    shuffle=True, \n",
    "    num_workers=0  # Set to 0 for compatibility\n",
    ")\n",
    "\n",
    "val_loader = DataLoader(\n",
    "    val_wiki_dataset, \n",
    "    batch_size=batch_size, \n",
    "    shuffle=False, \n",
    "    num_workers=0\n",
    ")\n",
    "\n",
    "test_loader = DataLoader(\n",
    "    test_wiki_dataset, \n",
    "    batch_size=batch_size, \n",
    "    shuffle=False, \n",
    "    num_workers=0\n",
    ")\n",
    "\n",
    "print(f\"\\nDataLoader Summary:\")\n",
    "print(f\"Training batches: {len(train_loader)}\")\n",
    "print(f\"Validation batches: {len(val_loader)}\")\n",
    "print(f\"Test batches: {len(test_loader)}\")\n",
    "print(f\"Batch size: {batch_size}\")\n",
    "print(f\"Sequence length: {sequence_length}\")\n",
    "\n",
    "# Test the DataLoader\n",
    "print(\"\\nTesting DataLoader...\")\n",
    "for batch_idx, (sequences, targets) in enumerate(train_loader):\n",
    "    print(f\"Batch {batch_idx + 1}:\")\n",
    "    print(f\"  Sequences shape: {sequences.shape}\")\n",
    "    print(f\"  Targets shape: {targets.shape}\")\n",
    "    print(f\"  Sample sequence: {sequences[0][:10].tolist()}\")\n",
    "    print(f\"  Sample target: {targets[0].item()}\")\n",
    "    \n",
    "    # Convert back to words for verification\n",
    "    sample_words = [idx_to_word[idx.item()] for idx in sequences[0]]\n",
    "    target_word = idx_to_word[targets[0].item()]\n",
    "    print(f\"  Sample words: {sample_words}\")\n",
    "    print(f\"  Target word: {target_word}\")\n",
    "    break  # Only show first batch\n",
    "\n",
    "print(\"\\nDataLoader created successfully!\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "GRU Language Model Summary:\n",
      "Vocabulary size: 28,712\n",
      "Embedding dimension: 200\n",
      "Hidden dimension: 400\n",
      "Number of layers: 3\n",
      "Dropout: 0.2\n",
      "Total parameters: 19,903,112\n",
      "Trainable parameters: 19,903,112\n",
      "Model device: cpu\n",
      "\n",
      "Testing model with sample batch...\n",
      "Input shape: torch.Size([64, 50])\n",
      "Output logits shape: torch.Size([64, 50, 28712])\n",
      "Hidden state shape: torch.Size([3, 64, 400])\n",
      "Target shape: torch.Size([64])\n",
      "Sample loss: 10.2651\n",
      "Sample accuracy: 0.0000\n",
      "\n",
      "Model initialized successfully!\n"
     ]
    }
   ],
   "source": [
    "# GRU Language Model Implementation\n",
    "\n",
    "import torch\n",
    "import torch.nn as nn\n",
    "import torch.optim as optim\n",
    "import torch.nn.functional as F\n",
    "import math\n",
    "\n",
    "class GRULanguageModel(nn.Module):\n",
    "    def __init__(self, vocab_size, embedding_dim=256, hidden_dim=512, num_layers=2, dropout=0.2):\n",
    "        \"\"\"\n",
    "        GRU-based Language Model for next word prediction\n",
    "        \n",
    "        Args:\n",
    "            vocab_size: Size of vocabulary\n",
    "            embedding_dim: Dimension of word embeddings\n",
    "            hidden_dim: Hidden dimension of GRU\n",
    "            num_layers: Number of GRU layers\n",
    "            dropout: Dropout probability\n",
    "        \"\"\"\n",
    "        super(GRULanguageModel, self).__init__()\n",
    "        \n",
    "        self.vocab_size = vocab_size\n",
    "        self.embedding_dim = embedding_dim\n",
    "        self.hidden_dim = hidden_dim\n",
    "        self.num_layers = num_layers\n",
    "        self.dropout = dropout\n",
    "        \n",
    "        # Word embedding layer\n",
    "        self.embedding = nn.Embedding(vocab_size, embedding_dim)\n",
    "        \n",
    "        # GRU layer(s)\n",
    "        self.gru = nn.GRU(\n",
    "            input_size=embedding_dim,\n",
    "            hidden_size=hidden_dim,\n",
    "            num_layers=num_layers,\n",
    "            dropout=dropout if num_layers > 1 else 0,\n",
    "            batch_first=True\n",
    "        )\n",
    "        \n",
    "        # Dropout layer\n",
    "        self.dropout_layer = nn.Dropout(dropout)\n",
    "        \n",
    "        # Output projection layer\n",
    "        self.output_projection = nn.Linear(hidden_dim, vocab_size)\n",
    "        \n",
    "        # Initialize weights\n",
    "        self.init_weights()\n",
    "    \n",
    "    def init_weights(self):\n",
    "        \"\"\"Initialize model weights\"\"\"\n",
    "        # Initialize embedding weights\n",
    "        nn.init.uniform_(self.embedding.weight, -0.1, 0.1)\n",
    "        \n",
    "        # Initialize GRU weights\n",
    "        for name, param in self.gru.named_parameters():\n",
    "            if 'weight' in name:\n",
    "                nn.init.orthogonal_(param)\n",
    "            elif 'bias' in name:\n",
    "                nn.init.zeros_(param)\n",
    "        \n",
    "        # Initialize output layer\n",
    "        nn.init.xavier_uniform_(self.output_projection.weight)\n",
    "        nn.init.zeros_(self.output_projection.bias)\n",
    "    \n",
    "    def forward(self, input_ids, hidden=None):\n",
    "        \"\"\"\n",
    "        Forward pass\n",
    "        \n",
    "        Args:\n",
    "            input_ids: Input token indices [batch_size, seq_len]\n",
    "            hidden: Hidden state from previous step\n",
    "            \n",
    "        Returns:\n",
    "            logits: Output logits [batch_size, seq_len, vocab_size]\n",
    "            hidden: Final hidden state\n",
    "        \"\"\"\n",
    "        batch_size, seq_len = input_ids.size()\n",
    "        \n",
    "        # Word embeddings\n",
    "        embeddings = self.embedding(input_ids)  # [batch_size, seq_len, embedding_dim]\n",
    "\n",
    "        embeddings = self.dropout_layer(embeddings)\n",
    "        \n",
    "        # GRU forward pass, 2 layers by default\n",
    "        gru_output, hidden = self.gru(embeddings, hidden)  # [batch_size, seq_len, hidden_dim]\n",
    "        \n",
    "        # Apply dropout to GRU output\n",
    "        gru_output = self.dropout_layer(gru_output)\n",
    "        \n",
    "        # Project to vocabulary size\n",
    "        logits = self.output_projection(gru_output)  # [batch_size, seq_len, vocab_size]\n",
    "        \n",
    "        return logits, hidden\n",
    "    \n",
    "    def init_hidden(self, batch_size):\n",
    "        \"\"\"Initialize hidden state\"\"\"\n",
    "        return torch.zeros(self.num_layers, batch_size, self.hidden_dim).to(next(self.parameters()).device)\n",
    "\n",
    "# Model hyperparameters\n",
    "vocab_size = len(vocab)\n",
    "embedding_dim = 200\n",
    "hidden_dim = 400\n",
    "num_layers = 3\n",
    "dropout = 0.2\n",
    "learning_rate = 0.0001\n",
    "\n",
    "# Initialize model\n",
    "model = GRULanguageModel(\n",
    "    vocab_size=vocab_size,\n",
    "    embedding_dim=embedding_dim,\n",
    "    hidden_dim=hidden_dim,\n",
    "    num_layers=num_layers,\n",
    "    dropout=dropout\n",
    ")\n",
    "\n",
    "# Move model to device\n",
    "model = model.to(device)\n",
    "\n",
    "# Loss function and optimizer\n",
    "criterion = nn.CrossEntropyLoss(ignore_index=vocab['<pad>'])  # Ignore padding tokens\n",
    "optimizer = optim.Adam(model.parameters(), lr=learning_rate)\n",
    "\n",
    "# Print model information\n",
    "total_params = sum(p.numel() for p in model.parameters())\n",
    "trainable_params = sum(p.numel() for p in model.parameters() if p.requires_grad)\n",
    "\n",
    "print(f\"\\nGRU Language Model Summary:\")\n",
    "print(f\"Vocabulary size: {vocab_size:,}\")\n",
    "print(f\"Embedding dimension: {embedding_dim}\")\n",
    "print(f\"Hidden dimension: {hidden_dim}\")\n",
    "print(f\"Number of layers: {num_layers}\")\n",
    "print(f\"Dropout: {dropout}\")\n",
    "print(f\"Total parameters: {total_params:,}\")\n",
    "print(f\"Trainable parameters: {trainable_params:,}\")\n",
    "print(f\"Model device: {next(model.parameters()).device}\")\n",
    "\n",
    "# Test the model with a sample batch\n",
    "print(f\"\\nTesting model with sample batch...\")\n",
    "model.eval()\n",
    "with torch.no_grad():\n",
    "    # Get a sample batch\n",
    "    sample_sequences, sample_targets = next(iter(train_loader))\n",
    "    sample_sequences = sample_sequences.to(device)\n",
    "    sample_targets = sample_targets.to(device)\n",
    "    \n",
    "    # Forward pass\n",
    "    logits, hidden = model(sample_sequences)\n",
    "    \n",
    "    print(f\"Input shape: {sample_sequences.shape}\")\n",
    "    print(f\"Output logits shape: {logits.shape}\")\n",
    "    print(f\"Hidden state shape: {hidden.shape}\")\n",
    "    print(f\"Target shape: {sample_targets.shape}\")\n",
    "    \n",
    "    # Calculate loss for the last token prediction\n",
    "    last_token_logits = logits[:, -1, :]  # [batch_size, vocab_size]\n",
    "    loss = criterion(last_token_logits, sample_targets)\n",
    "    print(f\"Sample loss: {loss.item():.4f}\")\n",
    "    \n",
    "    # Get predictions\n",
    "    predictions = torch.argmax(last_token_logits, dim=-1)\n",
    "    accuracy = (predictions == sample_targets).float().mean()\n",
    "    print(f\"Sample accuracy: {accuracy.item():.4f}\")\n",
    "\n",
    "print(f\"\\nModel initialized successfully!\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "🚀 Starting GRU Language Model Training...\n",
      "Model has 11,745,320 parameters\n",
      "Starting training for 10 epochs...\n",
      "Training batches: 27349\n",
      "Validation batches: 2869\n",
      "------------------------------------------------------------\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 1 Training:   4%|▎         | 1011/27349 [00:12<05:13, 83.90it/s, Loss=7.7516, Acc=0.0735]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 1000/27349:\n",
      "  Loss: 7.7534\n",
      "  Accuracy: 0.0737\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 1 Training:   7%|▋         | 2011/27349 [00:24<04:44, 89.07it/s, Loss=7.5865, Acc=0.0739]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 2000/27349:\n",
      "  Loss: 7.5885\n",
      "  Accuracy: 0.0740\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 1 Training:  11%|█         | 3007/27349 [00:37<05:36, 72.38it/s, Loss=7.5024, Acc=0.0770]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 3000/27349:\n",
      "  Loss: 7.5036\n",
      "  Accuracy: 0.0770\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 1 Training:  15%|█▍        | 4012/27349 [00:50<04:48, 80.94it/s, Loss=7.4338, Acc=0.0805]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 4000/27349:\n",
      "  Loss: 7.4336\n",
      "  Accuracy: 0.0805\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 1 Training:  18%|█▊        | 5014/27349 [01:02<05:16, 70.61it/s, Loss=7.3793, Acc=0.0832]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 5000/27349:\n",
      "  Loss: 7.3798\n",
      "  Accuracy: 0.0832\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 1 Training:  22%|██▏       | 6008/27349 [01:16<04:49, 73.84it/s, Loss=7.3384, Acc=0.0851]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 6000/27349:\n",
      "  Loss: 7.3388\n",
      "  Accuracy: 0.0851\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 1 Training:  26%|██▌       | 7008/27349 [01:30<04:48, 70.54it/s, Loss=7.3072, Acc=0.0864]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 7000/27349:\n",
      "  Loss: 7.3071\n",
      "  Accuracy: 0.0864\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 1 Training:  29%|██▉       | 8014/27349 [01:44<03:50, 83.87it/s, Loss=7.2775, Acc=0.0879]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 8000/27349:\n",
      "  Loss: 7.2781\n",
      "  Accuracy: 0.0878\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 1 Training:  33%|███▎      | 9008/27349 [01:57<04:04, 74.91it/s, Loss=7.2532, Acc=0.0894]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 9000/27349:\n",
      "  Loss: 7.2535\n",
      "  Accuracy: 0.0894\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 1 Training:  37%|███▋      | 10008/27349 [02:10<03:50, 75.19it/s, Loss=7.2320, Acc=0.0907]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 10000/27349:\n",
      "  Loss: 7.2323\n",
      "  Accuracy: 0.0907\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 1 Training:  40%|████      | 11008/27349 [02:23<03:39, 74.60it/s, Loss=7.2109, Acc=0.0921]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 11000/27349:\n",
      "  Loss: 7.2110\n",
      "  Accuracy: 0.0921\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 1 Training:  44%|████▍     | 12008/27349 [02:37<03:24, 74.85it/s, Loss=7.1923, Acc=0.0933]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 12000/27349:\n",
      "  Loss: 7.1928\n",
      "  Accuracy: 0.0932\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 1 Training:  48%|████▊     | 13008/27349 [02:50<03:27, 69.27it/s, Loss=7.1754, Acc=0.0945]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 13000/27349:\n",
      "  Loss: 7.1756\n",
      "  Accuracy: 0.0945\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 1 Training:  51%|█████     | 14009/27349 [03:04<03:07, 71.09it/s, Loss=7.1578, Acc=0.0956]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 14000/27349:\n",
      "  Loss: 7.1582\n",
      "  Accuracy: 0.0956\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 1 Training:  55%|█████▍    | 15014/27349 [03:18<02:48, 73.33it/s, Loss=7.1409, Acc=0.0968]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 15000/27349:\n",
      "  Loss: 7.1411\n",
      "  Accuracy: 0.0968\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 1 Training:  59%|█████▊    | 16011/27349 [03:32<02:32, 74.43it/s, Loss=7.1233, Acc=0.0979]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 16000/27349:\n",
      "  Loss: 7.1236\n",
      "  Accuracy: 0.0979\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 1 Training:  62%|██████▏   | 17011/27349 [03:46<02:22, 72.31it/s, Loss=7.1085, Acc=0.0990]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 17000/27349:\n",
      "  Loss: 7.1086\n",
      "  Accuracy: 0.0989\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 1 Training:  66%|██████▌   | 18015/27349 [03:59<01:49, 85.10it/s, Loss=7.0932, Acc=0.1001]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 18000/27349:\n",
      "  Loss: 7.0934\n",
      "  Accuracy: 0.1000\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 1 Training:  70%|██████▉   | 19009/27349 [04:11<01:54, 73.00it/s, Loss=7.0786, Acc=0.1010]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 19000/27349:\n",
      "  Loss: 7.0787\n",
      "  Accuracy: 0.1010\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 1 Training:  73%|███████▎  | 20008/27349 [04:23<01:40, 73.39it/s, Loss=7.0658, Acc=0.1019]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 20000/27349:\n",
      "  Loss: 7.0660\n",
      "  Accuracy: 0.1019\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 1 Training:  77%|███████▋  | 21007/27349 [04:37<01:29, 70.96it/s, Loss=7.0528, Acc=0.1028]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 21000/27349:\n",
      "  Loss: 7.0529\n",
      "  Accuracy: 0.1028\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 1 Training:  80%|████████  | 22014/27349 [04:51<01:07, 79.16it/s, Loss=7.0400, Acc=0.1037]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 22000/27349:\n",
      "  Loss: 7.0401\n",
      "  Accuracy: 0.1037\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 1 Training:  84%|████████▍ | 23010/27349 [05:02<00:52, 83.12it/s, Loss=7.0274, Acc=0.1047]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 23000/27349:\n",
      "  Loss: 7.0276\n",
      "  Accuracy: 0.1047\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 1 Training:  88%|████████▊ | 24009/27349 [05:14<00:38, 85.65it/s, Loss=7.0157, Acc=0.1055]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 24000/27349:\n",
      "  Loss: 7.0159\n",
      "  Accuracy: 0.1055\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 1 Training:  91%|█████████▏| 25012/27349 [05:28<00:30, 76.66it/s, Loss=7.0037, Acc=0.1064]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 25000/27349:\n",
      "  Loss: 7.0040\n",
      "  Accuracy: 0.1064\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 1 Training:  95%|█████████▌| 26007/27349 [05:42<00:18, 70.64it/s, Loss=6.9918, Acc=0.1074]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 26000/27349:\n",
      "  Loss: 6.9920\n",
      "  Accuracy: 0.1074\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 1 Training:  99%|█████████▉| 27008/27349 [05:56<00:04, 71.73it/s, Loss=6.9811, Acc=0.1082]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 27000/27349:\n",
      "  Loss: 6.9813\n",
      "  Accuracy: 0.1081\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 1 Training: 100%|██████████| 27349/27349 [06:01<00:00, 75.71it/s, Loss=6.9776, Acc=0.1084]\n",
      "Epoch 1 Validation: 100%|██████████| 2869/2869 [00:13<00:00, 213.55it/s, Val Loss=6.3928, Val Acc=0.1412]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "✓ New best model saved! Val Loss: 6.3928\n",
      "\n",
      "Epoch 1/10 Summary:\n",
      "  Train Loss: 6.9776 | Train Acc: 0.1084\n",
      "  Val Loss: 6.3928 | Val Acc: 0.1412\n",
      "  Time: 374.66s\n",
      "------------------------------------------------------------\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 2 Training:   4%|▎         | 1015/27349 [00:13<04:58, 88.15it/s, Loss=6.5892, Acc=0.1336]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 1000/27349:\n",
      "  Loss: 6.5877\n",
      "  Accuracy: 0.1337\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 2 Training:   7%|▋         | 2017/27349 [00:24<04:48, 87.76it/s, Loss=6.6029, Acc=0.1326]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 2000/27349:\n",
      "  Loss: 6.6032\n",
      "  Accuracy: 0.1326\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 2 Training:  11%|█         | 3011/27349 [00:36<04:53, 82.94it/s, Loss=6.6037, Acc=0.1328]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 3000/27349:\n",
      "  Loss: 6.6046\n",
      "  Accuracy: 0.1328\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 2 Training:  15%|█▍        | 4013/27349 [00:49<05:23, 72.11it/s, Loss=6.6030, Acc=0.1332]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 4000/27349:\n",
      "  Loss: 6.6037\n",
      "  Accuracy: 0.1332\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 2 Training:  18%|█▊        | 5007/27349 [01:03<05:05, 73.02it/s, Loss=6.5925, Acc=0.1341]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 5000/27349:\n",
      "  Loss: 6.5924\n",
      "  Accuracy: 0.1341\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 2 Training:  22%|██▏       | 6008/27349 [01:17<04:51, 73.29it/s, Loss=6.5870, Acc=0.1341]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 6000/27349:\n",
      "  Loss: 6.5870\n",
      "  Accuracy: 0.1341\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 2 Training:  26%|██▌       | 7009/27349 [01:30<03:55, 86.24it/s, Loss=6.5835, Acc=0.1342]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 7000/27349:\n",
      "  Loss: 6.5833\n",
      "  Accuracy: 0.1342\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 2 Training:  29%|██▉       | 8017/27349 [01:42<03:42, 86.83it/s, Loss=6.5813, Acc=0.1344]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 8000/27349:\n",
      "  Loss: 6.5812\n",
      "  Accuracy: 0.1344\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 2 Training:  33%|███▎      | 9011/27349 [01:54<03:45, 81.30it/s, Loss=6.5784, Acc=0.1346]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 9000/27349:\n",
      "  Loss: 6.5784\n",
      "  Accuracy: 0.1346\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 2 Training:  37%|███▋      | 10015/27349 [02:06<03:25, 84.26it/s, Loss=6.5757, Acc=0.1349]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 10000/27349:\n",
      "  Loss: 6.5757\n",
      "  Accuracy: 0.1349\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 2 Training:  40%|████      | 11010/27349 [02:19<03:37, 75.02it/s, Loss=6.5755, Acc=0.1352]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 11000/27349:\n",
      "  Loss: 6.5756\n",
      "  Accuracy: 0.1352\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 2 Training:  44%|████▍     | 12013/27349 [02:33<03:36, 70.77it/s, Loss=6.5710, Acc=0.1356]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 12000/27349:\n",
      "  Loss: 6.5712\n",
      "  Accuracy: 0.1356\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 2 Training:  48%|████▊     | 13012/27349 [02:47<03:25, 69.80it/s, Loss=6.5667, Acc=0.1358]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 13000/27349:\n",
      "  Loss: 6.5670\n",
      "  Accuracy: 0.1358\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 2 Training:  51%|█████     | 14011/27349 [03:01<03:07, 71.19it/s, Loss=6.5621, Acc=0.1362]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 14000/27349:\n",
      "  Loss: 6.5621\n",
      "  Accuracy: 0.1361\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 2 Training:  55%|█████▍    | 15014/27349 [03:14<02:21, 86.87it/s, Loss=6.5578, Acc=0.1364]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 15000/27349:\n",
      "  Loss: 6.5579\n",
      "  Accuracy: 0.1364\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 2 Training:  59%|█████▊    | 16013/27349 [03:25<02:11, 85.91it/s, Loss=6.5554, Acc=0.1367]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 16000/27349:\n",
      "  Loss: 6.5555\n",
      "  Accuracy: 0.1367\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 2 Training:  62%|██████▏   | 17012/27349 [03:37<01:59, 86.54it/s, Loss=6.5510, Acc=0.1369]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 17000/27349:\n",
      "  Loss: 6.5512\n",
      "  Accuracy: 0.1369\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 2 Training:  66%|██████▌   | 18011/27349 [03:49<01:55, 81.02it/s, Loss=6.5458, Acc=0.1373]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 18000/27349:\n",
      "  Loss: 6.5458\n",
      "  Accuracy: 0.1373\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 2 Training:  70%|██████▉   | 19010/27349 [04:01<01:41, 82.19it/s, Loss=6.5426, Acc=0.1375]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 19000/27349:\n",
      "  Loss: 6.5427\n",
      "  Accuracy: 0.1375\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 2 Training:  73%|███████▎  | 20014/27349 [04:13<01:27, 83.74it/s, Loss=6.5384, Acc=0.1378]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 20000/27349:\n",
      "  Loss: 6.5383\n",
      "  Accuracy: 0.1378\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 2 Training:  77%|███████▋  | 21016/27349 [04:26<01:11, 88.47it/s, Loss=6.5342, Acc=0.1381]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 21000/27349:\n",
      "  Loss: 6.5343\n",
      "  Accuracy: 0.1381\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 2 Training:  81%|████████  | 22016/27349 [04:38<01:03, 84.09it/s, Loss=6.5297, Acc=0.1383]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 22000/27349:\n",
      "  Loss: 6.5297\n",
      "  Accuracy: 0.1383\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 2 Training:  84%|████████▍ | 23015/27349 [04:50<00:53, 80.69it/s, Loss=6.5256, Acc=0.1385]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 23000/27349:\n",
      "  Loss: 6.5257\n",
      "  Accuracy: 0.1385\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 2 Training:  88%|████████▊ | 24010/27349 [05:03<00:37, 89.37it/s, Loss=6.5226, Acc=0.1388]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 24000/27349:\n",
      "  Loss: 6.5225\n",
      "  Accuracy: 0.1388\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 2 Training:  91%|█████████▏| 25009/27349 [05:15<00:28, 82.97it/s, Loss=6.5187, Acc=0.1390]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 25000/27349:\n",
      "  Loss: 6.5187\n",
      "  Accuracy: 0.1390\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 2 Training:  95%|█████████▌| 26011/27349 [05:29<00:15, 86.46it/s, Loss=6.5146, Acc=0.1392]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 26000/27349:\n",
      "  Loss: 6.5148\n",
      "  Accuracy: 0.1392\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 2 Training:  99%|█████████▉| 27013/27349 [05:41<00:03, 84.35it/s, Loss=6.5117, Acc=0.1394]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 27000/27349:\n",
      "  Loss: 6.5117\n",
      "  Accuracy: 0.1394\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 2 Training: 100%|██████████| 27349/27349 [05:45<00:00, 79.25it/s, Loss=6.5107, Acc=0.1394]\n",
      "Epoch 2 Validation: 100%|██████████| 2869/2869 [00:13<00:00, 217.27it/s, Val Loss=6.1653, Val Acc=0.1556]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "✓ New best model saved! Val Loss: 6.1653\n",
      "\n",
      "Epoch 2/10 Summary:\n",
      "  Train Loss: 6.5107 | Train Acc: 0.1394\n",
      "  Val Loss: 6.1653 | Val Acc: 0.1556\n",
      "  Time: 358.29s\n",
      "------------------------------------------------------------\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 3 Training:   4%|▎         | 1008/27349 [00:11<05:09, 85.08it/s, Loss=6.3332, Acc=0.1485]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 1000/27349:\n",
      "  Loss: 6.3346\n",
      "  Accuracy: 0.1485\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 3 Training:   7%|▋         | 2016/27349 [00:23<05:02, 83.86it/s, Loss=6.3267, Acc=0.1477]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 2000/27349:\n",
      "  Loss: 6.3273\n",
      "  Accuracy: 0.1476\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 3 Training:  11%|█         | 3015/27349 [00:35<04:37, 87.60it/s, Loss=6.3264, Acc=0.1480]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 3000/27349:\n",
      "  Loss: 6.3264\n",
      "  Accuracy: 0.1479\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 3 Training:  15%|█▍        | 4011/27349 [00:47<04:42, 82.67it/s, Loss=6.3222, Acc=0.1483]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 4000/27349:\n",
      "  Loss: 6.3228\n",
      "  Accuracy: 0.1483\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 3 Training:  18%|█▊        | 5011/27349 [01:00<05:09, 72.14it/s, Loss=6.3185, Acc=0.1490]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 5000/27349:\n",
      "  Loss: 6.3185\n",
      "  Accuracy: 0.1490\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 3 Training:  22%|██▏       | 6007/27349 [01:14<05:06, 69.58it/s, Loss=6.3172, Acc=0.1491]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 6000/27349:\n",
      "  Loss: 6.3166\n",
      "  Accuracy: 0.1490\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 3 Training:  26%|██▌       | 7011/27349 [01:27<03:47, 89.33it/s, Loss=6.3145, Acc=0.1493]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 7000/27349:\n",
      "  Loss: 6.3147\n",
      "  Accuracy: 0.1493\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 3 Training:  29%|██▉       | 8011/27349 [01:40<04:20, 74.36it/s, Loss=6.3119, Acc=0.1494]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 8000/27349:\n",
      "  Loss: 6.3118\n",
      "  Accuracy: 0.1494\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 3 Training:  33%|███▎      | 9008/27349 [01:54<04:15, 71.82it/s, Loss=6.3126, Acc=0.1493]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 9000/27349:\n",
      "  Loss: 6.3126\n",
      "  Accuracy: 0.1493\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 3 Training:  37%|███▋      | 10012/27349 [02:06<03:22, 85.61it/s, Loss=6.3118, Acc=0.1493]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 10000/27349:\n",
      "  Loss: 6.3119\n",
      "  Accuracy: 0.1493\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 3 Training:  40%|████      | 11007/27349 [02:20<03:52, 70.40it/s, Loss=6.3084, Acc=0.1495]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 11000/27349:\n",
      "  Loss: 6.3085\n",
      "  Accuracy: 0.1495\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 3 Training:  44%|████▍     | 12012/27349 [02:33<02:57, 86.60it/s, Loss=6.3083, Acc=0.1495]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 12000/27349:\n",
      "  Loss: 6.3085\n",
      "  Accuracy: 0.1495\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 3 Training:  48%|████▊     | 13013/27349 [02:45<02:45, 86.73it/s, Loss=6.3076, Acc=0.1496]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 13000/27349:\n",
      "  Loss: 6.3076\n",
      "  Accuracy: 0.1496\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 3 Training:  51%|█████     | 14015/27349 [02:58<02:55, 76.09it/s, Loss=6.3063, Acc=0.1498]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 14000/27349:\n",
      "  Loss: 6.3062\n",
      "  Accuracy: 0.1498\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 3 Training:  55%|█████▍    | 15008/27349 [03:11<02:27, 83.44it/s, Loss=6.3049, Acc=0.1497]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 15000/27349:\n",
      "  Loss: 6.3049\n",
      "  Accuracy: 0.1497\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 3 Training:  59%|█████▊    | 16011/27349 [03:24<02:31, 75.06it/s, Loss=6.3028, Acc=0.1498]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 16000/27349:\n",
      "  Loss: 6.3028\n",
      "  Accuracy: 0.1498\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 3 Training:  62%|██████▏   | 17013/27349 [03:36<02:06, 81.59it/s, Loss=6.3004, Acc=0.1500]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 17000/27349:\n",
      "  Loss: 6.3004\n",
      "  Accuracy: 0.1500\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 3 Training:  66%|██████▌   | 18016/27349 [03:48<01:53, 82.44it/s, Loss=6.2968, Acc=0.1502]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 18000/27349:\n",
      "  Loss: 6.2967\n",
      "  Accuracy: 0.1502\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 3 Training:  70%|██████▉   | 19013/27349 [04:00<01:58, 70.34it/s, Loss=6.2944, Acc=0.1504]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 19000/27349:\n",
      "  Loss: 6.2944\n",
      "  Accuracy: 0.1504\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 3 Training:  73%|███████▎  | 20008/27349 [04:15<01:45, 69.30it/s, Loss=6.2920, Acc=0.1505]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 20000/27349:\n",
      "  Loss: 6.2921\n",
      "  Accuracy: 0.1505\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 3 Training:  77%|███████▋  | 21016/27349 [04:28<01:16, 83.10it/s, Loss=6.2913, Acc=0.1505]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 21000/27349:\n",
      "  Loss: 6.2913\n",
      "  Accuracy: 0.1505\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 3 Training:  80%|████████  | 22009/27349 [04:41<01:10, 75.96it/s, Loss=6.2904, Acc=0.1504]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 22000/27349:\n",
      "  Loss: 6.2905\n",
      "  Accuracy: 0.1504\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 3 Training:  84%|████████▍ | 23015/27349 [04:54<00:47, 91.50it/s, Loss=6.2889, Acc=0.1506]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 23000/27349:\n",
      "  Loss: 6.2889\n",
      "  Accuracy: 0.1506\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 3 Training:  88%|████████▊ | 24014/27349 [05:06<00:41, 80.29it/s, Loss=6.2866, Acc=0.1507]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 24000/27349:\n",
      "  Loss: 6.2866\n",
      "  Accuracy: 0.1507\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 3 Training:  91%|█████████▏| 25009/27349 [05:18<00:27, 85.67it/s, Loss=6.2847, Acc=0.1508]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 25000/27349:\n",
      "  Loss: 6.2847\n",
      "  Accuracy: 0.1508\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 3 Training:  95%|█████████▌| 26016/27349 [05:30<00:16, 82.94it/s, Loss=6.2831, Acc=0.1509]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 26000/27349:\n",
      "  Loss: 6.2831\n",
      "  Accuracy: 0.1509\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 3 Training:  99%|█████████▉| 27011/27349 [05:42<00:04, 78.78it/s, Loss=6.2810, Acc=0.1510]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 27000/27349:\n",
      "  Loss: 6.2811\n",
      "  Accuracy: 0.1511\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 3 Training: 100%|██████████| 27349/27349 [05:47<00:00, 78.77it/s, Loss=6.2804, Acc=0.1511]\n",
      "Epoch 3 Validation: 100%|██████████| 2869/2869 [00:12<00:00, 232.81it/s, Val Loss=6.0207, Val Acc=0.1622]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "✓ New best model saved! Val Loss: 6.0207\n",
      "\n",
      "Epoch 3/10 Summary:\n",
      "  Train Loss: 6.2804 | Train Acc: 0.1511\n",
      "  Val Loss: 6.0207 | Val Acc: 0.1622\n",
      "  Time: 359.53s\n",
      "------------------------------------------------------------\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 4 Training:   4%|▎         | 1008/27349 [00:14<06:20, 69.24it/s, Loss=6.1462, Acc=0.1567]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 1000/27349:\n",
      "  Loss: 6.1466\n",
      "  Accuracy: 0.1568\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 4 Training:   7%|▋         | 2013/27349 [00:28<06:01, 70.06it/s, Loss=6.1271, Acc=0.1587]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 2000/27349:\n",
      "  Loss: 6.1262\n",
      "  Accuracy: 0.1587\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 4 Training:  11%|█         | 3010/27349 [00:42<05:39, 71.62it/s, Loss=6.1246, Acc=0.1582]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 3000/27349:\n",
      "  Loss: 6.1247\n",
      "  Accuracy: 0.1582\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 4 Training:  15%|█▍        | 4009/27349 [00:56<04:40, 83.15it/s, Loss=6.1220, Acc=0.1583]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 4000/27349:\n",
      "  Loss: 6.1219\n",
      "  Accuracy: 0.1583\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 4 Training:  18%|█▊        | 5011/27349 [01:08<04:56, 75.41it/s, Loss=6.1198, Acc=0.1581]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 5000/27349:\n",
      "  Loss: 6.1198\n",
      "  Accuracy: 0.1581\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 4 Training:  22%|██▏       | 6015/27349 [01:21<04:22, 81.37it/s, Loss=6.1236, Acc=0.1578]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 6000/27349:\n",
      "  Loss: 6.1233\n",
      "  Accuracy: 0.1578\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 4 Training:  26%|██▌       | 7010/27349 [01:33<03:56, 85.87it/s, Loss=6.1268, Acc=0.1577]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 7000/27349:\n",
      "  Loss: 6.1267\n",
      "  Accuracy: 0.1578\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 4 Training:  29%|██▉       | 8008/27349 [01:46<04:27, 72.36it/s, Loss=6.1280, Acc=0.1580]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 8000/27349:\n",
      "  Loss: 6.1284\n",
      "  Accuracy: 0.1580\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 4 Training:  33%|███▎      | 9013/27349 [01:58<03:37, 84.25it/s, Loss=6.1294, Acc=0.1583]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 9000/27349:\n",
      "  Loss: 6.1292\n",
      "  Accuracy: 0.1583\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 4 Training:  37%|███▋      | 10009/27349 [02:10<03:14, 89.18it/s, Loss=6.1282, Acc=0.1583]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 10000/27349:\n",
      "  Loss: 6.1283\n",
      "  Accuracy: 0.1583\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 4 Training:  40%|████      | 11009/27349 [02:21<03:21, 81.11it/s, Loss=6.1268, Acc=0.1585]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 11000/27349:\n",
      "  Loss: 6.1268\n",
      "  Accuracy: 0.1585\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 4 Training:  44%|████▍     | 12010/27349 [02:34<03:12, 79.61it/s, Loss=6.1267, Acc=0.1585]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 12000/27349:\n",
      "  Loss: 6.1266\n",
      "  Accuracy: 0.1585\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 4 Training:  48%|████▊     | 13008/27349 [02:45<02:54, 82.08it/s, Loss=6.1271, Acc=0.1586]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 13000/27349:\n",
      "  Loss: 6.1269\n",
      "  Accuracy: 0.1586\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 4 Training:  51%|█████     | 14014/27349 [02:59<03:08, 70.76it/s, Loss=6.1268, Acc=0.1587]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 14000/27349:\n",
      "  Loss: 6.1269\n",
      "  Accuracy: 0.1587\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 4 Training:  55%|█████▍    | 15016/27349 [03:11<02:34, 79.99it/s, Loss=6.1260, Acc=0.1589]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 15000/27349:\n",
      "  Loss: 6.1260\n",
      "  Accuracy: 0.1589\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 4 Training:  59%|█████▊    | 16010/27349 [03:23<02:19, 81.38it/s, Loss=6.1248, Acc=0.1590]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 16000/27349:\n",
      "  Loss: 6.1249\n",
      "  Accuracy: 0.1590\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 4 Training:  62%|██████▏   | 17010/27349 [03:35<02:08, 80.76it/s, Loss=6.1251, Acc=0.1590]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 17000/27349:\n",
      "  Loss: 6.1249\n",
      "  Accuracy: 0.1590\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 4 Training:  66%|██████▌   | 18013/27349 [03:48<01:58, 78.86it/s, Loss=6.1244, Acc=0.1591]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 18000/27349:\n",
      "  Loss: 6.1245\n",
      "  Accuracy: 0.1591\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 4 Training:  70%|██████▉   | 19012/27349 [04:01<01:39, 83.47it/s, Loss=6.1238, Acc=0.1592]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 19000/27349:\n",
      "  Loss: 6.1238\n",
      "  Accuracy: 0.1592\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 4 Training:  73%|███████▎  | 20008/27349 [04:14<01:44, 70.13it/s, Loss=6.1239, Acc=0.1592]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 20000/27349:\n",
      "  Loss: 6.1240\n",
      "  Accuracy: 0.1592\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 4 Training:  77%|███████▋  | 21007/27349 [04:28<01:30, 69.95it/s, Loss=6.1232, Acc=0.1593]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 21000/27349:\n",
      "  Loss: 6.1232\n",
      "  Accuracy: 0.1593\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 4 Training:  80%|████████  | 22015/27349 [04:41<01:02, 84.91it/s, Loss=6.1235, Acc=0.1593]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 22000/27349:\n",
      "  Loss: 6.1235\n",
      "  Accuracy: 0.1593\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 4 Training:  84%|████████▍ | 23007/27349 [04:54<01:02, 69.65it/s, Loss=6.1235, Acc=0.1594]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 23000/27349:\n",
      "  Loss: 6.1235\n",
      "  Accuracy: 0.1594\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 4 Training:  88%|████████▊ | 24012/27349 [05:07<00:44, 75.18it/s, Loss=6.1230, Acc=0.1593]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 24000/27349:\n",
      "  Loss: 6.1230\n",
      "  Accuracy: 0.1593\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 4 Training:  91%|█████████▏| 25013/27349 [05:19<00:33, 70.62it/s, Loss=6.1217, Acc=0.1594]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 25000/27349:\n",
      "  Loss: 6.1217\n",
      "  Accuracy: 0.1594\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 4 Training:  95%|█████████▌| 26011/27349 [05:34<00:19, 70.05it/s, Loss=6.1206, Acc=0.1596]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 26000/27349:\n",
      "  Loss: 6.1207\n",
      "  Accuracy: 0.1596\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 4 Training:  99%|█████████▊| 27007/27349 [05:48<00:04, 73.09it/s, Loss=6.1193, Acc=0.1597]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 27000/27349:\n",
      "  Loss: 6.1194\n",
      "  Accuracy: 0.1597\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 4 Training: 100%|██████████| 27349/27349 [05:52<00:00, 77.48it/s, Loss=6.1189, Acc=0.1597]\n",
      "Epoch 4 Validation: 100%|██████████| 2869/2869 [00:13<00:00, 220.40it/s, Val Loss=5.9235, Val Acc=0.1675]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "✓ New best model saved! Val Loss: 5.9235\n",
      "\n",
      "Epoch 4/10 Summary:\n",
      "  Train Loss: 6.1189 | Train Acc: 0.1597\n",
      "  Val Loss: 5.9235 | Val Acc: 0.1675\n",
      "  Time: 365.99s\n",
      "------------------------------------------------------------\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 5 Training:   4%|▎         | 1009/27349 [00:14<06:12, 70.66it/s, Loss=5.9767, Acc=0.1651]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 1000/27349:\n",
      "  Loss: 5.9765\n",
      "  Accuracy: 0.1650\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 5 Training:   7%|▋         | 2012/27349 [00:27<05:53, 71.63it/s, Loss=5.9835, Acc=0.1661]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 2000/27349:\n",
      "  Loss: 5.9814\n",
      "  Accuracy: 0.1662\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 5 Training:  11%|█         | 3016/27349 [00:39<04:51, 83.58it/s, Loss=5.9853, Acc=0.1657]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 3000/27349:\n",
      "  Loss: 5.9846\n",
      "  Accuracy: 0.1657\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 5 Training:  15%|█▍        | 4011/27349 [00:51<05:20, 72.91it/s, Loss=5.9870, Acc=0.1655]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 4000/27349:\n",
      "  Loss: 5.9870\n",
      "  Accuracy: 0.1655\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 5 Training:  18%|█▊        | 5008/27349 [01:03<05:05, 73.05it/s, Loss=5.9934, Acc=0.1655]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 5000/27349:\n",
      "  Loss: 5.9932\n",
      "  Accuracy: 0.1656\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 5 Training:  22%|██▏       | 6010/27349 [01:17<05:00, 71.06it/s, Loss=5.9907, Acc=0.1655]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 6000/27349:\n",
      "  Loss: 5.9909\n",
      "  Accuracy: 0.1655\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 5 Training:  26%|██▌       | 7007/27349 [01:31<04:47, 70.83it/s, Loss=5.9900, Acc=0.1656]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 7000/27349:\n",
      "  Loss: 5.9898\n",
      "  Accuracy: 0.1657\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 5 Training:  29%|██▉       | 8012/27349 [01:45<04:06, 78.42it/s, Loss=5.9886, Acc=0.1656]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 8000/27349:\n",
      "  Loss: 5.9886\n",
      "  Accuracy: 0.1656\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 5 Training:  33%|███▎      | 9010/27349 [01:58<04:17, 71.26it/s, Loss=5.9921, Acc=0.1655]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 9000/27349:\n",
      "  Loss: 5.9923\n",
      "  Accuracy: 0.1655\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 5 Training:  37%|███▋      | 10010/27349 [02:10<04:07, 70.07it/s, Loss=5.9929, Acc=0.1657]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 10000/27349:\n",
      "  Loss: 5.9928\n",
      "  Accuracy: 0.1657\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 5 Training:  40%|████      | 11010/27349 [02:24<03:38, 74.69it/s, Loss=5.9918, Acc=0.1658]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 11000/27349:\n",
      "  Loss: 5.9917\n",
      "  Accuracy: 0.1658\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 5 Training:  44%|████▍     | 12009/27349 [02:36<02:52, 89.13it/s, Loss=5.9923, Acc=0.1661]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 12000/27349:\n",
      "  Loss: 5.9920\n",
      "  Accuracy: 0.1661\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 5 Training:  48%|████▊     | 13017/27349 [02:47<02:41, 88.61it/s, Loss=5.9939, Acc=0.1660]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 13000/27349:\n",
      "  Loss: 5.9937\n",
      "  Accuracy: 0.1660\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 5 Training:  51%|█████     | 14016/27349 [02:59<02:36, 85.06it/s, Loss=5.9941, Acc=0.1661]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 14000/27349:\n",
      "  Loss: 5.9941\n",
      "  Accuracy: 0.1661\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 5 Training:  55%|█████▍    | 15014/27349 [03:11<02:18, 89.15it/s, Loss=5.9962, Acc=0.1662]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 15000/27349:\n",
      "  Loss: 5.9961\n",
      "  Accuracy: 0.1662\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 5 Training:  59%|█████▊    | 16012/27349 [03:22<02:14, 84.60it/s, Loss=5.9954, Acc=0.1663]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 16000/27349:\n",
      "  Loss: 5.9954\n",
      "  Accuracy: 0.1663\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 5 Training:  62%|██████▏   | 17014/27349 [03:35<02:09, 79.63it/s, Loss=5.9955, Acc=0.1663]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 17000/27349:\n",
      "  Loss: 5.9954\n",
      "  Accuracy: 0.1663\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 5 Training:  66%|██████▌   | 18013/27349 [03:47<01:47, 86.71it/s, Loss=5.9962, Acc=0.1664]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 18000/27349:\n",
      "  Loss: 5.9960\n",
      "  Accuracy: 0.1664\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 5 Training:  70%|██████▉   | 19010/27349 [03:59<01:41, 82.55it/s, Loss=5.9970, Acc=0.1663]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 19000/27349:\n",
      "  Loss: 5.9971\n",
      "  Accuracy: 0.1663\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 5 Training:  73%|███████▎  | 20016/27349 [04:11<01:23, 88.24it/s, Loss=5.9969, Acc=0.1663]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 20000/27349:\n",
      "  Loss: 5.9969\n",
      "  Accuracy: 0.1663\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 5 Training:  77%|███████▋  | 21013/27349 [04:23<01:23, 75.55it/s, Loss=5.9970, Acc=0.1664]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 21000/27349:\n",
      "  Loss: 5.9970\n",
      "  Accuracy: 0.1664\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 5 Training:  80%|████████  | 22010/27349 [04:37<01:14, 71.40it/s, Loss=5.9972, Acc=0.1663]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 22000/27349:\n",
      "  Loss: 5.9973\n",
      "  Accuracy: 0.1663\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 5 Training:  84%|████████▍ | 23010/27349 [04:51<01:00, 71.92it/s, Loss=5.9964, Acc=0.1665]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 23000/27349:\n",
      "  Loss: 5.9964\n",
      "  Accuracy: 0.1665\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 5 Training:  88%|████████▊ | 24013/27349 [05:05<00:47, 70.30it/s, Loss=5.9954, Acc=0.1666]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 24000/27349:\n",
      "  Loss: 5.9954\n",
      "  Accuracy: 0.1666\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 5 Training:  91%|█████████▏| 25010/27349 [05:18<00:30, 76.52it/s, Loss=5.9945, Acc=0.1666]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 25000/27349:\n",
      "  Loss: 5.9945\n",
      "  Accuracy: 0.1666\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 5 Training:  95%|█████████▌| 26011/27349 [05:32<00:19, 70.16it/s, Loss=5.9940, Acc=0.1667]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 26000/27349:\n",
      "  Loss: 5.9940\n",
      "  Accuracy: 0.1667\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 5 Training:  99%|█████████▉| 27011/27349 [05:46<00:04, 73.18it/s, Loss=5.9927, Acc=0.1668]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 27000/27349:\n",
      "  Loss: 5.9927\n",
      "  Accuracy: 0.1668\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 5 Training: 100%|██████████| 27349/27349 [05:51<00:00, 77.89it/s, Loss=5.9923, Acc=0.1669]\n",
      "Epoch 5 Validation: 100%|██████████| 2869/2869 [00:12<00:00, 225.34it/s, Val Loss=5.8582, Val Acc=0.1721]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "✓ New best model saved! Val Loss: 5.8582\n",
      "\n",
      "Epoch 5/10 Summary:\n",
      "  Train Loss: 5.9923 | Train Acc: 0.1669\n",
      "  Val Loss: 5.8582 | Val Acc: 0.1721\n",
      "  Time: 363.86s\n",
      "------------------------------------------------------------\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 6 Training:   4%|▎         | 1014/27349 [00:12<05:53, 74.44it/s, Loss=5.8568, Acc=0.1733]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 1000/27349:\n",
      "  Loss: 5.8560\n",
      "  Accuracy: 0.1734\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 6 Training:   7%|▋         | 2007/27349 [00:26<05:42, 73.94it/s, Loss=5.8624, Acc=0.1730]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 2000/27349:\n",
      "  Loss: 5.8631\n",
      "  Accuracy: 0.1729\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 6 Training:  11%|█         | 3008/27349 [00:39<05:07, 79.06it/s, Loss=5.8747, Acc=0.1725]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 3000/27349:\n",
      "  Loss: 5.8744\n",
      "  Accuracy: 0.1725\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 6 Training:  15%|█▍        | 4015/27349 [00:52<04:43, 82.32it/s, Loss=5.8715, Acc=0.1730]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 4000/27349:\n",
      "  Loss: 5.8714\n",
      "  Accuracy: 0.1730\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 6 Training:  18%|█▊        | 5014/27349 [01:05<05:18, 70.19it/s, Loss=5.8731, Acc=0.1730]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 5000/27349:\n",
      "  Loss: 5.8735\n",
      "  Accuracy: 0.1730\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 6 Training:  22%|██▏       | 6013/27349 [01:19<05:02, 70.43it/s, Loss=5.8764, Acc=0.1726]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 6000/27349:\n",
      "  Loss: 5.8765\n",
      "  Accuracy: 0.1725\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 6 Training:  26%|██▌       | 7007/27349 [01:31<04:46, 70.90it/s, Loss=5.8749, Acc=0.1729]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 7000/27349:\n",
      "  Loss: 5.8751\n",
      "  Accuracy: 0.1728\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 6 Training:  29%|██▉       | 8009/27349 [01:45<04:29, 71.85it/s, Loss=5.8780, Acc=0.1729]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 8000/27349:\n",
      "  Loss: 5.8779\n",
      "  Accuracy: 0.1729\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 6 Training:  33%|███▎      | 9008/27349 [01:57<03:47, 80.75it/s, Loss=5.8791, Acc=0.1729]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 9000/27349:\n",
      "  Loss: 5.8793\n",
      "  Accuracy: 0.1729\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 6 Training:  37%|███▋      | 10010/27349 [02:11<04:05, 70.61it/s, Loss=5.8802, Acc=0.1728]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 10000/27349:\n",
      "  Loss: 5.8803\n",
      "  Accuracy: 0.1728\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 6 Training:  40%|████      | 11010/27349 [02:25<03:43, 73.12it/s, Loss=5.8833, Acc=0.1726]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 11000/27349:\n",
      "  Loss: 5.8831\n",
      "  Accuracy: 0.1726\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 6 Training:  44%|████▍     | 12013/27349 [02:38<03:11, 80.26it/s, Loss=5.8836, Acc=0.1726]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 12000/27349:\n",
      "  Loss: 5.8838\n",
      "  Accuracy: 0.1726\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 6 Training:  48%|████▊     | 13010/27349 [02:52<03:07, 76.59it/s, Loss=5.8855, Acc=0.1727]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 13000/27349:\n",
      "  Loss: 5.8855\n",
      "  Accuracy: 0.1727\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 6 Training:  51%|█████     | 14008/27349 [03:05<02:45, 80.55it/s, Loss=5.8846, Acc=0.1727]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 14000/27349:\n",
      "  Loss: 5.8848\n",
      "  Accuracy: 0.1727\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 6 Training:  55%|█████▍    | 15010/27349 [03:18<02:35, 79.48it/s, Loss=5.8853, Acc=0.1728]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 15000/27349:\n",
      "  Loss: 5.8853\n",
      "  Accuracy: 0.1728\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 6 Training:  59%|█████▊    | 16012/27349 [03:31<02:32, 74.34it/s, Loss=5.8847, Acc=0.1728]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 16000/27349:\n",
      "  Loss: 5.8848\n",
      "  Accuracy: 0.1728\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 6 Training:  62%|██████▏   | 17009/27349 [03:44<02:09, 79.89it/s, Loss=5.8854, Acc=0.1728]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 17000/27349:\n",
      "  Loss: 5.8854\n",
      "  Accuracy: 0.1728\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 6 Training:  66%|██████▌   | 18009/27349 [03:57<02:05, 74.50it/s, Loss=5.8861, Acc=0.1728]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 18000/27349:\n",
      "  Loss: 5.8859\n",
      "  Accuracy: 0.1728\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 6 Training:  70%|██████▉   | 19011/27349 [04:09<01:41, 82.15it/s, Loss=5.8865, Acc=0.1727]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 19000/27349:\n",
      "  Loss: 5.8866\n",
      "  Accuracy: 0.1727\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 6 Training:  73%|███████▎  | 20014/27349 [04:21<01:37, 75.35it/s, Loss=5.8864, Acc=0.1728]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 20000/27349:\n",
      "  Loss: 5.8865\n",
      "  Accuracy: 0.1728\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 6 Training:  77%|███████▋  | 21008/27349 [04:33<01:28, 71.62it/s, Loss=5.8866, Acc=0.1728]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 21000/27349:\n",
      "  Loss: 5.8867\n",
      "  Accuracy: 0.1728\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 6 Training:  80%|████████  | 22011/27349 [04:46<01:14, 71.81it/s, Loss=5.8870, Acc=0.1727]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 22000/27349:\n",
      "  Loss: 5.8869\n",
      "  Accuracy: 0.1727\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 6 Training:  84%|████████▍ | 23013/27349 [04:58<00:49, 87.55it/s, Loss=5.8875, Acc=0.1726]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 23000/27349:\n",
      "  Loss: 5.8875\n",
      "  Accuracy: 0.1726\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 6 Training:  88%|████████▊ | 24009/27349 [05:11<00:47, 71.02it/s, Loss=5.8879, Acc=0.1727]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 24000/27349:\n",
      "  Loss: 5.8878\n",
      "  Accuracy: 0.1727\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 6 Training:  91%|█████████▏| 25012/27349 [05:24<00:31, 74.30it/s, Loss=5.8872, Acc=0.1728]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 25000/27349:\n",
      "  Loss: 5.8873\n",
      "  Accuracy: 0.1727\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 6 Training:  95%|█████████▌| 26017/27349 [05:37<00:15, 87.59it/s, Loss=5.8869, Acc=0.1728]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 26000/27349:\n",
      "  Loss: 5.8870\n",
      "  Accuracy: 0.1728\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 6 Training:  99%|█████████▉| 27011/27349 [05:49<00:03, 85.04it/s, Loss=5.8871, Acc=0.1728]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 27000/27349:\n",
      "  Loss: 5.8870\n",
      "  Accuracy: 0.1728\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 6 Training: 100%|██████████| 27349/27349 [05:53<00:00, 77.41it/s, Loss=5.8867, Acc=0.1729]\n",
      "Epoch 6 Validation: 100%|██████████| 2869/2869 [00:13<00:00, 220.12it/s, Val Loss=5.8124, Val Acc=0.1742]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "✓ New best model saved! Val Loss: 5.8124\n",
      "\n",
      "Epoch 6/10 Summary:\n",
      "  Train Loss: 5.8867 | Train Acc: 0.1729\n",
      "  Val Loss: 5.8124 | Val Acc: 0.1742\n",
      "  Time: 366.34s\n",
      "------------------------------------------------------------\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 7 Training:   4%|▎         | 1011/27349 [00:13<06:12, 70.71it/s, Loss=5.7615, Acc=0.1791]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 1000/27349:\n",
      "  Loss: 5.7592\n",
      "  Accuracy: 0.1794\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 7 Training:   7%|▋         | 2007/27349 [00:27<06:00, 70.34it/s, Loss=5.7728, Acc=0.1778]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 2000/27349:\n",
      "  Loss: 5.7736\n",
      "  Accuracy: 0.1779\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 7 Training:  11%|█         | 3012/27349 [00:39<05:13, 77.57it/s, Loss=5.7678, Acc=0.1781]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 3000/27349:\n",
      "  Loss: 5.7674\n",
      "  Accuracy: 0.1780\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 7 Training:  15%|█▍        | 4014/27349 [00:52<04:26, 87.49it/s, Loss=5.7711, Acc=0.1778]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 4000/27349:\n",
      "  Loss: 5.7713\n",
      "  Accuracy: 0.1778\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 7 Training:  18%|█▊        | 5017/27349 [01:03<04:16, 87.01it/s, Loss=5.7689, Acc=0.1779]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 5000/27349:\n",
      "  Loss: 5.7694\n",
      "  Accuracy: 0.1779\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 7 Training:  22%|██▏       | 6016/27349 [01:15<04:10, 85.07it/s, Loss=5.7737, Acc=0.1779]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 6000/27349:\n",
      "  Loss: 5.7737\n",
      "  Accuracy: 0.1779\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 7 Training:  26%|██▌       | 7015/27349 [01:27<03:54, 86.73it/s, Loss=5.7727, Acc=0.1782]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 7000/27349:\n",
      "  Loss: 5.7730\n",
      "  Accuracy: 0.1782\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 7 Training:  29%|██▉       | 8007/27349 [01:38<04:23, 73.43it/s, Loss=5.7749, Acc=0.1781]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 8000/27349:\n",
      "  Loss: 5.7749\n",
      "  Accuracy: 0.1781\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 7 Training:  33%|███▎      | 9013/27349 [01:51<03:35, 85.20it/s, Loss=5.7755, Acc=0.1781]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 9000/27349:\n",
      "  Loss: 5.7752\n",
      "  Accuracy: 0.1781\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 7 Training:  37%|███▋      | 10008/27349 [02:04<03:15, 88.51it/s, Loss=5.7776, Acc=0.1779]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 10000/27349:\n",
      "  Loss: 5.7775\n",
      "  Accuracy: 0.1779\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 7 Training:  40%|████      | 11014/27349 [02:16<03:10, 85.81it/s, Loss=5.7803, Acc=0.1779]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 11000/27349:\n",
      "  Loss: 5.7801\n",
      "  Accuracy: 0.1779\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 7 Training:  44%|████▍     | 12009/27349 [02:28<03:06, 82.14it/s, Loss=5.7801, Acc=0.1778]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 12000/27349:\n",
      "  Loss: 5.7803\n",
      "  Accuracy: 0.1778\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 7 Training:  48%|████▊     | 13009/27349 [02:41<03:16, 72.87it/s, Loss=5.7831, Acc=0.1776]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 13000/27349:\n",
      "  Loss: 5.7831\n",
      "  Accuracy: 0.1776\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 7 Training:  51%|█████     | 14007/27349 [02:54<02:59, 74.50it/s, Loss=5.7828, Acc=0.1778]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 14000/27349:\n",
      "  Loss: 5.7828\n",
      "  Accuracy: 0.1778\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 7 Training:  55%|█████▍    | 15008/27349 [03:07<02:29, 82.30it/s, Loss=5.7848, Acc=0.1778]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 15000/27349:\n",
      "  Loss: 5.7847\n",
      "  Accuracy: 0.1778\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 7 Training:  59%|█████▊    | 16010/27349 [03:20<02:23, 79.20it/s, Loss=5.7862, Acc=0.1777]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 16000/27349:\n",
      "  Loss: 5.7860\n",
      "  Accuracy: 0.1777\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 7 Training:  62%|██████▏   | 17010/27349 [03:32<01:57, 87.87it/s, Loss=5.7884, Acc=0.1776]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 17000/27349:\n",
      "  Loss: 5.7883\n",
      "  Accuracy: 0.1776\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 7 Training:  66%|██████▌   | 18009/27349 [03:43<01:53, 82.60it/s, Loss=5.7899, Acc=0.1775]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 18000/27349:\n",
      "  Loss: 5.7899\n",
      "  Accuracy: 0.1775\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 7 Training:  70%|██████▉   | 19017/27349 [03:55<01:37, 85.38it/s, Loss=5.7908, Acc=0.1775]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 19000/27349:\n",
      "  Loss: 5.7909\n",
      "  Accuracy: 0.1775\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 7 Training:  73%|███████▎  | 20016/27349 [04:07<01:24, 86.92it/s, Loss=5.7908, Acc=0.1776]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 20000/27349:\n",
      "  Loss: 5.7908\n",
      "  Accuracy: 0.1776\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 7 Training:  77%|███████▋  | 21012/27349 [04:19<01:14, 85.19it/s, Loss=5.7912, Acc=0.1777]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 21000/27349:\n",
      "  Loss: 5.7911\n",
      "  Accuracy: 0.1777\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 7 Training:  80%|████████  | 22013/27349 [04:30<01:05, 81.86it/s, Loss=5.7917, Acc=0.1778]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 22000/27349:\n",
      "  Loss: 5.7916\n",
      "  Accuracy: 0.1779\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 7 Training:  84%|████████▍ | 23008/27349 [04:43<00:53, 81.90it/s, Loss=5.7927, Acc=0.1779]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 23000/27349:\n",
      "  Loss: 5.7927\n",
      "  Accuracy: 0.1779\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 9 Training:  37%|███▋      | 10014/27349 [02:14<03:23, 84.98it/s, Loss=5.6244, Acc=0.1874]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 10000/27349:\n",
      "  Loss: 5.6242\n",
      "  Accuracy: 0.1874\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 9 Training:  40%|████      | 11007/27349 [02:27<03:17, 82.70it/s, Loss=5.6248, Acc=0.1873]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 11000/27349:\n",
      "  Loss: 5.6249\n",
      "  Accuracy: 0.1873\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 9 Training:  43%|████▎     | 11786/27349 [02:37<03:17, 78.88it/s, Loss=5.6256, Acc=0.1873]IOPub message rate exceeded.\n",
      "The Jupyter server will temporarily stop sending output\n",
      "to the client in order to avoid crashing it.\n",
      "To change this limit, set the config variable\n",
      "`--ServerApp.iopub_msg_rate_limit`.\n",
      "\n",
      "Current values:\n",
      "ServerApp.iopub_msg_rate_limit=1000.0 (msgs/sec)\n",
      "ServerApp.rate_limit_window=3.0 (secs)\n",
      "\n",
      "Epoch 10 Training:  51%|█████     | 14014/27349 [02:54<02:50, 77.99it/s, Loss=5.5613, Acc=0.1913]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 14000/27349:\n",
      "  Loss: 5.5612\n",
      "  Accuracy: 0.1913\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 10 Training:  55%|█████▍    | 15009/27349 [03:08<02:52, 71.41it/s, Loss=5.5627, Acc=0.1913]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 15000/27349:\n",
      "  Loss: 5.5627\n",
      "  Accuracy: 0.1913\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 10 Training:  59%|█████▊    | 16014/27349 [03:22<02:32, 74.32it/s, Loss=5.5644, Acc=0.1913]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 16000/27349:\n",
      "  Loss: 5.5645\n",
      "  Accuracy: 0.1913\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 10 Training:  62%|██████▏   | 17014/27349 [03:34<02:00, 86.06it/s, Loss=5.5656, Acc=0.1912]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 17000/27349:\n",
      "  Loss: 5.5657\n",
      "  Accuracy: 0.1912\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 10 Training:  66%|██████▌   | 18018/27349 [03:46<01:43, 89.74it/s, Loss=5.5674, Acc=0.1912]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 18000/27349:\n",
      "  Loss: 5.5674\n",
      "  Accuracy: 0.1912\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 10 Training:  70%|██████▉   | 19009/27349 [03:59<01:58, 70.18it/s, Loss=5.5702, Acc=0.1909]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 19000/27349:\n",
      "  Loss: 5.5701\n",
      "  Accuracy: 0.1909\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 10 Training:  73%|███████▎  | 20011/27349 [04:13<01:42, 71.87it/s, Loss=5.5713, Acc=0.1910]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 20000/27349:\n",
      "  Loss: 5.5714\n",
      "  Accuracy: 0.1910\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 10 Training:  77%|███████▋  | 21007/27349 [04:27<01:30, 70.13it/s, Loss=5.5728, Acc=0.1909]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 21000/27349:\n",
      "  Loss: 5.5729\n",
      "  Accuracy: 0.1909\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 10 Training:  80%|████████  | 22011/27349 [04:39<01:02, 85.44it/s, Loss=5.5738, Acc=0.1908]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 22000/27349:\n",
      "  Loss: 5.5739\n",
      "  Accuracy: 0.1908\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 10 Training:  84%|████████▍ | 23010/27349 [04:51<00:50, 85.69it/s, Loss=5.5752, Acc=0.1908]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 23000/27349:\n",
      "  Loss: 5.5751\n",
      "  Accuracy: 0.1908\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 10 Training:  88%|████████▊ | 24007/27349 [05:03<00:45, 74.01it/s, Loss=5.5765, Acc=0.1907]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 24000/27349:\n",
      "  Loss: 5.5765\n",
      "  Accuracy: 0.1907\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 10 Training:  91%|█████████▏| 25007/27349 [05:17<00:32, 71.09it/s, Loss=5.5777, Acc=0.1907]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 25000/27349:\n",
      "  Loss: 5.5776\n",
      "  Accuracy: 0.1907\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 10 Training:  95%|█████████▌| 26014/27349 [05:31<00:16, 82.19it/s, Loss=5.5785, Acc=0.1907]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 26000/27349:\n",
      "  Loss: 5.5785\n",
      "  Accuracy: 0.1907\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 10 Training:  99%|█████████▉| 27008/27349 [05:45<00:04, 82.89it/s, Loss=5.5790, Acc=0.1908]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Batch 27000/27349:\n",
      "  Loss: 5.5790\n",
      "  Accuracy: 0.1908\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 10 Training: 100%|██████████| 27349/27349 [05:49<00:00, 78.33it/s, Loss=5.5795, Acc=0.1908]\n",
      "Epoch 10 Validation: 100%|██████████| 2869/2869 [00:12<00:00, 231.55it/s, Val Loss=5.6805, Val Acc=0.1846]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "✓ New best model saved! Val Loss: 5.6805\n",
      "\n",
      "Epoch 10/10 Summary:\n",
      "  Train Loss: 5.5795 | Train Acc: 0.1908\n",
      "  Val Loss: 5.6805 | Val Acc: 0.1846\n",
      "  Time: 361.54s\n",
      "------------------------------------------------------------\n",
      "\n",
      "Training completed in 3618.42s\n",
      "Best validation loss: 5.6805\n",
      "Loaded best model weights\n"
     ]
    },
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAABdEAAAHqCAYAAADrpwd3AAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjMsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvZiW1igAAAAlwSFlzAAAPYQAAD2EBqD+naQAA6FBJREFUeJzs3Xd4FFUXx/HvppAQQui9JfTei4A06VWQIghSRREBEUFBlC5FUBGkSAsgTekgNaAIAlIUkF6k9ybSIWXfP+6bhDWFAEkm5fd5njywd2Znzm5mYPbsmXNtdrvdjoiIiIiIiIiIiIiIhOFkdQAiIiIiIiIiIiIiInGVkugiIiIiIiIiIiIiIhFQEl1EREREREREREREJAJKoouIiIiIiIiIiIiIREBJdBERERERERERERGRCCiJLiIiIiIiIiIiIiISASXRRUREREREREREREQioCS6iIiIiIiIiIiIiEgElEQXEREREREREREREYmAkugikmC0b98eb2/v53ruoEGDsNls0RtQHHP69GlsNhszZ86M9X3bbDYGDRoU8njmzJnYbDZOnz791Od6e3vTvn37aI3nRY4VERERkcRA19aR07V1KF1bi0hioCS6iMQ4m80WpZ9NmzZZHWqi16NHD2w2GydOnIhwnf79+2Oz2fjrr79iMbJnd/HiRQYNGsTevXutDiVE8IetMWPGWB2KiIiIxFO6to4/dG0dew4fPozNZsPd3Z1bt25ZHY6IJEAuVgcgIgnf999/7/B49uzZ+Pn5hRkvUKDAC+1n6tSpBAUFPddzP/30U/r27ftC+08IWrduzfjx45k3bx4DBgwId5358+dTpEgRihYt+tz7efPNN2nZsiVubm7PvY2nuXjxIoMHD8bb25vixYs7LHuRY0VERETESrq2jj90bR175syZQ8aMGfnnn39YtGgRb731lqXxiEjCoyS6iMS4Nm3aODz+/fff8fPzCzP+X/fv38fDwyPK+3F1dX2u+ABcXFxwcdE/ieXKlSN37tzMnz8/3Av97du3c+rUKUaOHPlC+3F2dsbZ2fmFtvEiXuRYEREREbGSrq3jD11bxw673c68efN44403OHXqFHPnzo2zSfR79+6RLFkyq8MQkeegdi4iEidUrVqVwoUL88cff1C5cmU8PDz45JNPAFi+fDn169cnc+bMuLm5kStXLoYOHUpgYKDDNv7bi+/J1hlTpkwhV65cuLm5UaZMGXbt2uXw3PD6NtpsNrp168ayZcsoXLgwbm5uFCpUiLVr14aJf9OmTZQuXRp3d3dy5crFd999F+VekFu2bKF58+Zkz54dNzc3smXLxgcffMCDBw/CvD5PT08uXLhA48aN8fT0JF26dPTu3TvMe3Hr1i3at29PihQpSJkyJe3atYvybY2tW7fmyJEj/Pnnn2GWzZs3D5vNRqtWrXj8+DEDBgygVKlSpEiRgmTJklGpUiV++eWXp+4jvL6NdrudYcOGkTVrVjw8PKhWrRoHDx4M89ybN2/Su3dvihQpgqenJ15eXtStW5d9+/aFrLNp0ybKlCkDQIcOHUJuaw7uWRle38Z79+7x4Ycfki1bNtzc3MiXLx9jxozBbrc7rPcsx8Xzunr1Kp06dSJDhgy4u7tTrFgxZs2aFWa9BQsWUKpUKZInT46XlxdFihThm2++CVnu7+/P4MGDyZMnD+7u7qRJk4aXX34ZPz+/aItVRERE4h5dW+vaOjFdW2/dupXTp0/TsmVLWrZsyebNmzl//nyY9YKCgvjmm28oUqQI7u7upEuXjjp16rB7926H9ebMmUPZsmXx8PAgVapUVK5cmfXr1zvE/GRP+mD/7Tcf/Hv59ddf6dq1K+nTpydr1qwAnDlzhq5du5IvXz6SJk1KmjRpaN68ebh97W/dusUHH3yAt7c3bm5uZM2albZt23L9+nXu3r1LsmTJeP/998M87/z58zg7OzNixIgovpMiEhl9NSwiccaNGzeoW7cuLVu2pE2bNmTIkAEwFx+enp706tULT09Pfv75ZwYMGMDt27cZPXr0U7c7b9487ty5wzvvvIPNZuOLL77gtdde4+TJk0+tmvjtt99YsmQJXbt2JXny5IwbN46mTZty9uxZ0qRJA8CePXuoU6cOmTJlYvDgwQQGBjJkyBDSpUsXpde9cOFC7t+/z7vvvkuaNGnYuXMn48eP5/z58yxcuNBh3cDAQGrXrk25cuUYM2YMGzZs4MsvvyRXrly8++67gLlgfvXVV/ntt9/o0qULBQoUYOnSpbRr1y5K8bRu3ZrBgwczb948SpYs6bDvH3/8kUqVKpE9e3auX7/OtGnTaNWqFZ07d+bOnTtMnz6d2rVrs3PnzjC3eT7NgAEDGDZsGPXq1aNevXr8+eef1KpVi8ePHzusd/LkSZYtW0bz5s3x8fHhypUrfPfdd1SpUoVDhw6ROXNmChQowJAhQxgwYABvv/02lSpVAqBChQrh7ttut9OoUSN++eUXOnXqRPHixVm3bh19+vThwoULfP311w7rR+W4eF4PHjygatWqnDhxgm7duuHj48PChQtp3749t27dCrlA9vPzo1WrVlSvXp1Ro0YBphfk1q1bQ9YZNGgQI0aM4K233qJs2bLcvn2b3bt38+eff1KzZs0XilNERETiNl1b69o6sVxbz507l1y5clGmTBkKFy6Mh4cH8+fPp0+fPg7rderUiZkzZ1K3bl3eeustAgIC2LJlC7///julS5cGYPDgwQwaNIgKFSowZMgQkiRJwo4dO/j555+pVatWlN//J3Xt2pV06dIxYMAA7t27B8CuXbvYtm0bLVu2JGvWrJw+fZpJkyZRtWpVDh06FHLXyN27d6lUqRKHDx+mY8eOlCxZkuvXr7NixQrOnz9P8eLFadKkCT/88ANfffWVwx0J8+fPx26307p16+eKW0T+wy4iEsvee+89+3//+alSpYodsE+ePDnM+vfv3w8z9s4779g9PDzsDx8+DBlr166dPUeOHCGPT506ZQfsadKksd+8eTNkfPny5XbAvnLlypCxgQMHhokJsCdJksR+4sSJkLF9+/bZAfv48eNDxho2bGj38PCwX7hwIWTs+PHjdhcXlzDbDE94r2/EiBF2m81mP3PmjMPrA+xDhgxxWLdEiRL2UqVKhTxetmyZHbB/8cUXIWMBAQH2SpUq2QG7r6/vU2MqU6aMPWvWrPbAwMCQsbVr19oB+3fffReyzUePHjk8759//rFnyJDB3rFjR4dxwD5w4MCQx76+vnbAfurUKbvdbrdfvXrVniRJEnv9+vXtQUFBIet98skndsDerl27kLGHDx86xGW3m9+1m5ubw3uza9euCF/vf4+V4Pds2LBhDus1a9bMbrPZHI6BqB4X4Qk+JkePHh3hOmPHjrUD9jlz5oSMPX782F6+fHm7p6en/fbt23a73W5///337V5eXvaAgIAIt1WsWDF7/fr1I41JRERE4jddWz/99ena2kho19Z2u7lOTpMmjb1///4hY2+88Ya9WLFiDuv9/PPPdsDeo0ePMNsIfo+OHz9ud3Jysjdp0iTMe/Lk+/jf9z9Yjhw5HN7b4N/Lyy+/HOaaPbzjdPv2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",
      "text/plain": [
       "<Figure size 1500x500 with 2 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "✅ Training completed!\n",
      "📁 Model saved as 'gru_language_model.pth'\n",
      "🎯 Final validation accuracy: 0.1846\n"
     ]
    }
   ],
   "source": [
    "# Train the GRU Language Model\n",
    "\n",
    "import torch\n",
    "import torch.nn as nn\n",
    "import time\n",
    "from tqdm import tqdm\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "def train_epoch(model, train_loader, criterion, optimizer, device, epoch):\n",
    "    \"\"\"Train the model for one epoch\"\"\"\n",
    "    model.train()\n",
    "    total_loss = 0\n",
    "    total_samples = 0\n",
    "    correct_predictions = 0\n",
    "    \n",
    "    # Progress bar\n",
    "    pbar = tqdm(train_loader, desc=f'Epoch {epoch+1} Training')\n",
    "    \n",
    "    for batch_idx, (sequences, targets) in enumerate(pbar):\n",
    "        # Move data to device\n",
    "        sequences = sequences.to(device)\n",
    "        targets = targets.to(device)\n",
    "        \n",
    "        # Zero gradients\n",
    "        optimizer.zero_grad()\n",
    "        \n",
    "        # Forward pass\n",
    "        logits, hidden = model(sequences)\n",
    "        \n",
    "        # Calculate loss (predict next token from last timestep)\n",
    "        last_token_logits = logits[:, -1, :]  # [batch_size, vocab_size]\n",
    "        loss = criterion(last_token_logits, targets)\n",
    "        \n",
    "        # Backward pass\n",
    "        loss.backward()\n",
    "        \n",
    "        # Gradient clipping to prevent exploding gradients\n",
    "        torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm=1.0)\n",
    "        \n",
    "        # Update weights\n",
    "        optimizer.step()\n",
    "        \n",
    "        # Statistics\n",
    "        total_loss += loss.item()\n",
    "        total_samples += targets.size(0)\n",
    "        \n",
    "        # Calculate accuracy\n",
    "        predictions = torch.argmax(last_token_logits, dim=-1)\n",
    "        correct_predictions += (predictions == targets).sum().item()\n",
    "        \n",
    "        # Update progress bar\n",
    "        avg_loss = total_loss / (batch_idx + 1)\n",
    "        accuracy = correct_predictions / total_samples\n",
    "        pbar.set_postfix({\n",
    "            'Loss': f'{avg_loss:.4f}',\n",
    "            'Acc': f'{accuracy:.4f}'\n",
    "        })\n",
    "        \n",
    "        # Print detailed stats every 1000 batches\n",
    "        if (batch_idx + 1) % 1000 == 0:\n",
    "            print(f'\\nBatch {batch_idx+1}/{len(train_loader)}:')\n",
    "            print(f'  Loss: {avg_loss:.4f}')\n",
    "            print(f'  Accuracy: {accuracy:.4f}')\n",
    "    \n",
    "    avg_loss = total_loss / len(train_loader)\n",
    "    accuracy = correct_predictions / total_samples\n",
    "    \n",
    "    return avg_loss, accuracy\n",
    "\n",
    "def validate_epoch(model, val_loader, criterion, device, epoch):\n",
    "    \"\"\"Validate the model\"\"\"\n",
    "    model.eval()\n",
    "    total_loss = 0\n",
    "    total_samples = 0\n",
    "    correct_predictions = 0\n",
    "    \n",
    "    with torch.no_grad():\n",
    "        pbar = tqdm(val_loader, desc=f'Epoch {epoch+1} Validation')\n",
    "        \n",
    "        for sequences, targets in pbar:\n",
    "            # Move data to device\n",
    "            sequences = sequences.to(device)\n",
    "            targets = targets.to(device)\n",
    "            \n",
    "            # Forward pass\n",
    "            logits, hidden = model(sequences)\n",
    "            \n",
    "            # Calculate loss\n",
    "            last_token_logits = logits[:, -1, :]\n",
    "            loss = criterion(last_token_logits, targets)\n",
    "            \n",
    "            # Statistics\n",
    "            total_loss += loss.item()\n",
    "            total_samples += targets.size(0)\n",
    "            \n",
    "            # Calculate accuracy\n",
    "            predictions = torch.argmax(last_token_logits, dim=-1)\n",
    "            correct_predictions += (predictions == targets).sum().item()\n",
    "            \n",
    "            # Update progress bar\n",
    "            avg_loss = total_loss / len(val_loader) if len(val_loader) > 0 else 0\n",
    "            accuracy = correct_predictions / total_samples\n",
    "            pbar.set_postfix({\n",
    "                'Val Loss': f'{avg_loss:.4f}',\n",
    "                'Val Acc': f'{accuracy:.4f}'\n",
    "            })\n",
    "    \n",
    "    avg_loss = total_loss / len(val_loader)\n",
    "    accuracy = correct_predictions / total_samples\n",
    "    \n",
    "    return avg_loss, accuracy\n",
    "\n",
    "def train_model(model, train_loader, val_loader, criterion, optimizer, device, num_epochs=10):\n",
    "    \"\"\"Complete training loop\"\"\"\n",
    "    \n",
    "    # Training history\n",
    "    train_losses = []\n",
    "    train_accuracies = []\n",
    "    val_losses = []\n",
    "    val_accuracies = []\n",
    "    \n",
    "    best_val_loss = float('inf')\n",
    "    best_model_state = None\n",
    "    \n",
    "    print(f\"Starting training for {num_epochs} epochs...\")\n",
    "    print(f\"Training batches: {len(train_loader)}\")\n",
    "    print(f\"Validation batches: {len(val_loader)}\")\n",
    "    print(\"-\" * 60)\n",
    "    \n",
    "    start_time = time.time()\n",
    "    \n",
    "    for epoch in range(num_epochs):\n",
    "        epoch_start_time = time.time()\n",
    "        \n",
    "        # Training\n",
    "        train_loss, train_acc = train_epoch(model, train_loader, criterion, optimizer, device, epoch)\n",
    "        \n",
    "        # Validation\n",
    "        val_loss, val_acc = validate_epoch(model, val_loader, criterion, device, epoch)\n",
    "        \n",
    "        # Save best model\n",
    "        if val_loss < best_val_loss:\n",
    "            best_val_loss = val_loss\n",
    "            best_model_state = model.state_dict().copy()\n",
    "            print(f\"✓ New best model saved! Val Loss: {val_loss:.4f}\")\n",
    "        \n",
    "        # Record history\n",
    "        train_losses.append(train_loss)\n",
    "        train_accuracies.append(train_acc)\n",
    "        val_losses.append(val_loss)\n",
    "        val_accuracies.append(val_acc)\n",
    "        \n",
    "        # Print epoch summary\n",
    "        epoch_time = time.time() - epoch_start_time\n",
    "        print(f\"\\nEpoch {epoch+1}/{num_epochs} Summary:\")\n",
    "        print(f\"  Train Loss: {train_loss:.4f} | Train Acc: {train_acc:.4f}\")\n",
    "        print(f\"  Val Loss: {val_loss:.4f} | Val Acc: {val_acc:.4f}\")\n",
    "        print(f\"  Time: {epoch_time:.2f}s\")\n",
    "        print(\"-\" * 60)\n",
    "    \n",
    "    total_time = time.time() - start_time\n",
    "    print(f\"\\nTraining completed in {total_time:.2f}s\")\n",
    "    print(f\"Best validation loss: {best_val_loss:.4f}\")\n",
    "    \n",
    "    # Load best model\n",
    "    if best_model_state is not None:\n",
    "        model.load_state_dict(best_model_state)\n",
    "        print(\"Loaded best model weights\")\n",
    "    \n",
    "    return {\n",
    "        'train_losses': train_losses,\n",
    "        'train_accuracies': train_accuracies,\n",
    "        'val_losses': val_losses,\n",
    "        'val_accuracies': val_accuracies,\n",
    "        'best_val_loss': best_val_loss\n",
    "    }\n",
    "\n",
    "def plot_training_history(history):\n",
    "    \"\"\"Plot training curves\"\"\"\n",
    "    fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(15, 5))\n",
    "    \n",
    "    # Loss plot\n",
    "    ax1.plot(history['train_losses'], label='Train Loss', color='blue')\n",
    "    ax1.plot(history['val_losses'], label='Val Loss', color='red')\n",
    "    ax1.set_title('Training and Validation Loss')\n",
    "    ax1.set_xlabel('Epoch')\n",
    "    ax1.set_ylabel('Loss')\n",
    "    ax1.legend()\n",
    "    ax1.grid(True)\n",
    "    \n",
    "    # Accuracy plot\n",
    "    ax2.plot(history['train_accuracies'], label='Train Accuracy', color='blue')\n",
    "    ax2.plot(history['val_accuracies'], label='Val Accuracy', color='red')\n",
    "    ax2.set_title('Training and Validation Accuracy')\n",
    "    ax2.set_xlabel('Epoch')\n",
    "    ax2.set_ylabel('Accuracy')\n",
    "    ax2.legend()\n",
    "    ax2.grid(True)\n",
    "    \n",
    "    plt.tight_layout()\n",
    "    plt.show()\n",
    "\n",
    "# Start training\n",
    "print(\"🚀 Starting GRU Language Model Training...\")\n",
    "print(f\"Model has {sum(p.numel() for p in model.parameters()):,} parameters\")\n",
    "\n",
    "# Training parameters\n",
    "num_epochs = 10\n",
    "\n",
    "# Train the model\n",
    "history = train_model(\n",
    "    model=model,\n",
    "    train_loader=train_loader,\n",
    "    val_loader=val_loader,\n",
    "    criterion=criterion,\n",
    "    optimizer=optimizer,\n",
    "    device=device,\n",
    "    num_epochs=num_epochs\n",
    ")\n",
    "\n",
    "# Plot results\n",
    "plot_training_history(history)\n",
    "\n",
    "# Save the trained model\n",
    "torch.save({\n",
    "    'model_state_dict': model.state_dict(),\n",
    "    'optimizer_state_dict': optimizer.state_dict(),\n",
    "    'history': history,\n",
    "    'vocab': vocab,\n",
    "    'model_config': {\n",
    "        'vocab_size': vocab_size,\n",
    "        'embedding_dim': embedding_dim,\n",
    "        'hidden_dim': hidden_dim,\n",
    "        'num_layers': num_layers,\n",
    "        'dropout': dropout\n",
    "    }\n",
    "}, 'gru_language_model.pth')\n",
    "\n",
    "print(\"\\n✅ Training completed!\")\n",
    "print(\"📁 Model saved as 'gru_language_model.pth'\")\n",
    "print(f\"🎯 Final validation accuracy: {history['val_accuracies'][-1]:.4f}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "🧪 Testing the trained GRU model...\n",
      "\n",
      "📋 Testing with example sentences:\n",
      "============================================================\n",
      "\n",
      "1. Input: 'The cat sat on the'\n",
      "   Predicted: 'surface'\n",
      "   Top 3: ['ground', 'unk', 'surface']\n",
      "   Complete: 'The cat sat on the surface'\n",
      "\n",
      "2. Input: 'I love to eat'\n",
      "   Predicted: 'it'\n",
      "   Top 3: ['the', 'unk', 'a']\n",
      "   Complete: 'I love to eat it'\n",
      "\n",
      "3. Input: 'The weather today is'\n",
      "   Predicted: 'not'\n",
      "   Top 3: ['a', 'the', 'also']\n",
      "   Complete: 'The weather today is not'\n",
      "\n",
      "4. Input: 'Machine learning is'\n",
      "   Predicted: 'unk'\n",
      "   Top 3: ['a', 'the', 'to']\n",
      "   Complete: 'Machine learning is unk'\n",
      "\n",
      "5. Input: 'In the future we will'\n",
      "   Predicted: 'also'\n",
      "   Top 3: ['be', 'not', 'have']\n",
      "   Complete: 'In the future we will also'\n",
      "\n",
      "6. Input: 'The president of the United'\n",
      "   Predicted: 'states'\n",
      "   Top 3: ['states', 'nations', 'kingdom']\n",
      "   Complete: 'The president of the United states'\n",
      "\n",
      "7. Input: 'Scientists have discovered a new'\n",
      "   Predicted: 'front'\n",
      "   Top 3: ['unk', 'rate', 'generation']\n",
      "   Complete: 'Scientists have discovered a new front'\n",
      "\n",
      "8. Input: 'The book was very'\n",
      "   Predicted: 'well'\n",
      "   Top 3: ['difficult', 'successful', 'unk']\n",
      "   Complete: 'The book was very well'\n",
      "\n",
      "🤖 Interactive Text Prediction Mode\n",
      "Enter a sentence and I'll predict the next word!\n",
      "Type 'quit' to exit, 'generate' to generate multiple words\n",
      "------------------------------------------------------------\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Enter text:  I'm living in the United\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "🔍 Analyzing: 'I'm living in the United'\n",
      "🎯 Predicted next word: 'states'\n",
      "\n",
      "📊 Top 10 candidates:\n",
      "   1. states          (0.9700)\n",
      "   2. kingdom         (0.0207)\n",
      "   3. nations         (0.0015)\n",
      "   4. notes           (0.0007)\n",
      "   5. century         (0.0005)\n",
      "   6. of              (0.0005)\n",
      "   7. class           (0.0003)\n",
      "   8. and             (0.0003)\n",
      "   9. area            (0.0003)\n",
      "  10. body            (0.0002)\n",
      "\n",
      "📝 Complete sentence: 'I'm living in the United states'\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Enter text:  Hello world! I am an AI, Who\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "🔍 Analyzing: 'Hello world! I am an AI, Who'\n",
      "🎯 Predicted next word: 'can'\n",
      "\n",
      "📊 Top 10 candidates:\n",
      "   1. is              (0.2028)\n",
      "   2. can             (0.1560)\n",
      "   3. has             (0.0769)\n",
      "   4. was             (0.0745)\n",
      "   5. will            (0.0722)\n",
      "   6. would           (0.0555)\n",
      "   7. had             (0.0524)\n",
      "   8. are             (0.0269)\n",
      "   9. must            (0.0220)\n",
      "  10. could           (0.0192)\n",
      "\n",
      "📝 Complete sentence: 'Hello world! I am an AI, Who can'\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Enter text:  Hello world! I am an AI, Who can save\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "🔍 Analyzing: 'Hello world! I am an AI, Who can save'\n",
      "🎯 Predicted next word: 'on'\n",
      "\n",
      "📊 Top 10 candidates:\n",
      "   1. the             (0.2553)\n",
      "   2. them            (0.1336)\n",
      "   3. their           (0.0590)\n",
      "   4. it              (0.0569)\n",
      "   5. a               (0.0536)\n",
      "   6. any             (0.0456)\n",
      "   7. him             (0.0238)\n",
      "   8. in              (0.0199)\n",
      "   9. unk             (0.0173)\n",
      "  10. for             (0.0163)\n",
      "\n",
      "📝 Complete sentence: 'Hello world! I am an AI, Who can save on'\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Enter text:  Hello world! I am an AI, Who can save o\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "🔍 Analyzing: 'Hello world! I am an AI, Who can save o'\n",
      "🎯 Predicted next word: 'offer'\n",
      "\n",
      "📊 Top 10 candidates:\n",
      "   1. malley          (0.4640)\n",
      "   2. brien           (0.1186)\n",
      "   3. kong            (0.0807)\n",
      "   4. acid            (0.0541)\n",
      "   5. unk             (0.0349)\n",
      "   6. acids           (0.0252)\n",
      "   7. vegas           (0.0179)\n",
      "   8. intelligence    (0.0147)\n",
      "   9. márquez         (0.0140)\n",
      "  10. shara           (0.0132)\n",
      "\n",
      "📝 Complete sentence: 'Hello world! I am an AI, Who can save o offer'\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Enter text:  Hello world! I am an AI, Who can save on\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "🔍 Analyzing: 'Hello world! I am an AI, Who can save on'\n",
      "🎯 Predicted next word: 'an'\n",
      "\n",
      "📊 Top 10 candidates:\n",
      "   1. the             (0.3911)\n",
      "   2. their           (0.0885)\n",
      "   3. a               (0.0861)\n",
      "   4. any             (0.0433)\n",
      "   5. them            (0.0273)\n",
      "   6. its             (0.0225)\n",
      "   7. how             (0.0185)\n",
      "   8. earth           (0.0175)\n",
      "   9. unk             (0.0164)\n",
      "  10. it              (0.0161)\n",
      "\n",
      "📝 Complete sentence: 'Hello world! I am an AI, Who can save on an'\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Enter text:  Hello world! I am an AI, Who can save on an\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "🔍 Analyzing: 'Hello world! I am an AI, Who can save on an'\n",
      "🎯 Predicted next word: 'injury'\n",
      "\n",
      "📊 Top 10 candidates:\n",
      "   1. average         (0.1661)\n",
      "   2. adult           (0.0491)\n",
      "   3. air             (0.0469)\n",
      "   4. alternative     (0.0424)\n",
      "   5. hour            (0.0380)\n",
      "   6. alien           (0.0378)\n",
      "   7. unk             (0.0339)\n",
      "   8. attempt         (0.0321)\n",
      "   9. eye             (0.0292)\n",
      "  10. emotional       (0.0270)\n",
      "\n",
      "📝 Complete sentence: 'Hello world! I am an AI, Who can save on an injury'\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Enter text:  Hundreds of thousands of\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "🔍 Analyzing: 'Hundreds of thousands of'\n",
      "🎯 Predicted next word: 'aircraft'\n",
      "\n",
      "📊 Top 10 candidates:\n",
      "   1. men             (0.0865)\n",
      "   2. aircraft        (0.0743)\n",
      "   3. unk             (0.0587)\n",
      "   4. dollars         (0.0540)\n",
      "   5. water           (0.0515)\n",
      "   6. people          (0.0484)\n",
      "   7. women           (0.0411)\n",
      "   8. thousands       (0.0338)\n",
      "   9. equipment       (0.0296)\n",
      "  10. birds           (0.0279)\n",
      "\n",
      "📝 Complete sentence: 'Hundreds of thousands of aircraft'\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Enter text:  Hundreds of thousands of aircraft\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "🔍 Analyzing: 'Hundreds of thousands of aircraft'\n",
      "🎯 Predicted next word: 'aircraft'\n",
      "\n",
      "📊 Top 10 candidates:\n",
      "   1. and             (0.1315)\n",
      "   2. are             (0.0874)\n",
      "   3. in              (0.0748)\n",
      "   4. were            (0.0634)\n",
      "   5. from            (0.0377)\n",
      "   6. per             (0.0353)\n",
      "   7. the             (0.0328)\n",
      "   8. with            (0.0317)\n",
      "   9. can             (0.0263)\n",
      "  10. including       (0.0249)\n",
      "\n",
      "📝 Complete sentence: 'Hundreds of thousands of aircraft aircraft'\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Enter text:  Hundreds of thousands of people\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "🔍 Analyzing: 'Hundreds of thousands of people'\n",
      "🎯 Predicted next word: 'caused'\n",
      "\n",
      "📊 Top 10 candidates:\n",
      "   1. are             (0.1147)\n",
      "   2. were            (0.1138)\n",
      "   3. and             (0.1099)\n",
      "   4. in              (0.1043)\n",
      "   5. of              (0.0441)\n",
      "   6. from            (0.0321)\n",
      "   7. the             (0.0255)\n",
      "   8. with            (0.0240)\n",
      "   9. who             (0.0230)\n",
      "  10. can             (0.0229)\n",
      "\n",
      "📝 Complete sentence: 'Hundreds of thousands of people caused'\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Enter text:  News, features and analysis from\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "🔍 Analyzing: 'News, features and analysis from'\n",
      "🎯 Predicted next word: 'the'\n",
      "\n",
      "📊 Top 10 candidates:\n",
      "   1. the             (0.5477)\n",
      "   2. a               (0.1049)\n",
      "   3. their           (0.0521)\n",
      "   4. its             (0.0361)\n",
      "   5. other           (0.0278)\n",
      "   6. unk             (0.0276)\n",
      "   7. an              (0.0173)\n",
      "   8. this            (0.0163)\n",
      "   9. both            (0.0113)\n",
      "  10. all             (0.0105)\n",
      "\n",
      "📝 Complete sentence: 'News, features and analysis from the'\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Enter text:  News, features and analysis from the\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "🔍 Analyzing: 'News, features and analysis from the'\n",
      "🎯 Predicted next word: 'olympic'\n",
      "\n",
      "📊 Top 10 candidates:\n",
      "   1. unk             (0.1007)\n",
      "   2. game            (0.0437)\n",
      "   3. process         (0.0434)\n",
      "   4. world           (0.0416)\n",
      "   5. same            (0.0402)\n",
      "   6. first           (0.0317)\n",
      "   7. air             (0.0252)\n",
      "   8. core            (0.0240)\n",
      "   9. project         (0.0236)\n",
      "  10. flight          (0.0234)\n",
      "\n",
      "📝 Complete sentence: 'News, features and analysis from the olympic'\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "🔍 Analyzing: 'Hello, world! I am Archer. What is your'\n",
      "🎯 Predicted next word: 'way'\n",
      "\n",
      "📊 Top 10 candidates:\n",
      "   1. unk             (0.3377)\n",
      "   2. first           (0.1444)\n",
      "   3. own             (0.0813)\n",
      "   4. love            (0.0381)\n",
      "   5. most            (0.0293)\n",
      "   6. best            (0.0262)\n",
      "   7. name            (0.0258)\n",
      "   8. use             (0.0219)\n",
      "   9. last            (0.0216)\n",
      "  10. great           (0.0179)\n",
      "\n",
      "📝 Complete sentence: 'Hello, world! I am Archer. What is your way'\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Enter text:  He does not want to drink this\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "🔍 Analyzing: 'He does not want to drink this'\n",
      "🎯 Predicted next word: 'time'\n",
      "\n",
      "📊 Top 10 candidates:\n",
      "   1. unk             (0.1353)\n",
      "   2. with            (0.0529)\n",
      "   3. to              (0.0496)\n",
      "   4. as              (0.0481)\n",
      "   5. in              (0.0475)\n",
      "   6. work            (0.0421)\n",
      "   7. use             (0.0342)\n",
      "   8. other           (0.0289)\n",
      "   9. name            (0.0271)\n",
      "  10. time            (0.0265)\n",
      "\n",
      "📝 Complete sentence: 'He does not want to drink this time'\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Enter text:  He does not like this kind of \n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "🔍 Analyzing: 'He does not like this kind of'\n",
      "🎯 Predicted next word: 'two'\n",
      "\n",
      "📊 Top 10 candidates:\n",
      "   1. the             (0.1570)\n",
      "   2. their           (0.0626)\n",
      "   3. a               (0.0570)\n",
      "   4. his             (0.0422)\n",
      "   5. unk             (0.0353)\n",
      "   6. ireland         (0.0305)\n",
      "   7. interest        (0.0260)\n",
      "   8. all             (0.0240)\n",
      "   9. each            (0.0233)\n",
      "  10. those           (0.0233)\n",
      "\n",
      "📝 Complete sentence: 'He does not like this kind of two'\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Enter text:  Hello\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "🔍 Analyzing: 'Hello'\n",
      "🎯 Predicted next word: 'and'\n",
      "\n",
      "📊 Top 10 candidates:\n",
      "   1. unk             (0.3862)\n",
      "   2. and             (0.3561)\n",
      "   3. the             (0.0491)\n",
      "   4. in              (0.0238)\n",
      "   5. were            (0.0133)\n",
      "   6. which           (0.0103)\n",
      "   7. of              (0.0087)\n",
      "   8. university      (0.0077)\n",
      "   9. a               (0.0076)\n",
      "  10. who             (0.0076)\n",
      "\n",
      "📝 Complete sentence: 'Hello and'\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Enter text:  How are\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "🔍 Analyzing: 'How are'\n",
      "🎯 Predicted next word: 'found'\n",
      "\n",
      "📊 Top 10 candidates:\n",
      "   1. also            (0.0793)\n",
      "   2. the             (0.0764)\n",
      "   3. a               (0.0539)\n",
      "   4. not             (0.0448)\n",
      "   5. one             (0.0417)\n",
      "   6. used            (0.0397)\n",
      "   7. unk             (0.0294)\n",
      "   8. made            (0.0287)\n",
      "   9. called          (0.0266)\n",
      "  10. in              (0.0251)\n",
      "\n",
      "📝 Complete sentence: 'How are found'\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Enter text:  How are you, fine\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "🔍 Analyzing: 'How are you, fine'\n",
      "🎯 Predicted next word: 'and'\n",
      "\n",
      "📊 Top 10 candidates:\n",
      "   1. and             (0.6350)\n",
      "   2. unk             (0.1204)\n",
      "   3. the             (0.0433)\n",
      "   4. in              (0.0298)\n",
      "   5. with            (0.0241)\n",
      "   6. as              (0.0140)\n",
      "   7. to              (0.0128)\n",
      "   8. for             (0.0088)\n",
      "   9. or              (0.0087)\n",
      "  10. life            (0.0059)\n",
      "\n",
      "📝 Complete sentence: 'How are you, fine and'\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Enter text:  How are you, find and\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "🔍 Analyzing: 'How are you, find and'\n",
      "🎯 Predicted next word: 'unk'\n",
      "\n",
      "📊 Top 10 candidates:\n",
      "   1. the             (0.1755)\n",
      "   2. a               (0.0967)\n",
      "   3. unk             (0.0864)\n",
      "   4. that            (0.0842)\n",
      "   5. as              (0.0489)\n",
      "   6. their           (0.0350)\n",
      "   7. by              (0.0348)\n",
      "   8. in              (0.0306)\n",
      "   9. for             (0.0229)\n",
      "  10. to              (0.0229)\n",
      "\n",
      "📝 Complete sentence: 'How are you, find and unk'\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Enter text:  How are you, fine and\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "🔍 Analyzing: 'How are you, fine and'\n",
      "🎯 Predicted next word: 'the'\n",
      "\n",
      "📊 Top 10 candidates:\n",
      "   1. unk             (0.3697)\n",
      "   2. the             (0.2034)\n",
      "   3. other           (0.0370)\n",
      "   4. a               (0.0316)\n",
      "   5. was             (0.0235)\n",
      "   6. is              (0.0154)\n",
      "   7. and             (0.0153)\n",
      "   8. others          (0.0151)\n",
      "   9. in              (0.0133)\n",
      "  10. it              (0.0130)\n",
      "\n",
      "📝 Complete sentence: 'How are you, fine and the'\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Enter text:  How are you, find and thank\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "🔍 Analyzing: 'How are you, find and thank'\n",
      "🎯 Predicted next word: 'when'\n",
      "\n",
      "📊 Top 10 candidates:\n",
      "   1. the             (0.1869)\n",
      "   2. by              (0.1784)\n",
      "   3. for             (0.0763)\n",
      "   4. a               (0.0529)\n",
      "   5. unk             (0.0462)\n",
      "   6. and             (0.0384)\n",
      "   7. in              (0.0366)\n",
      "   8. as              (0.0358)\n",
      "   9. to              (0.0271)\n",
      "  10. that            (0.0182)\n",
      "\n",
      "📝 Complete sentence: 'How are you, find and thank when'\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Enter text:  How are you, fine and thank\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "🔍 Analyzing: 'How are you, fine and thank'\n",
      "🎯 Predicted next word: 'richard'\n",
      "\n",
      "📊 Top 10 candidates:\n",
      "   1. by              (0.1482)\n",
      "   2. the             (0.1446)\n",
      "   3. unk             (0.1255)\n",
      "   4. for             (0.0554)\n",
      "   5. and             (0.0469)\n",
      "   6. a               (0.0303)\n",
      "   7. in              (0.0259)\n",
      "   8. john            (0.0249)\n",
      "   9. it              (0.0236)\n",
      "  10. as              (0.0173)\n",
      "\n",
      "📝 Complete sentence: 'How are you, fine and thank richard'\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Enter text:  How are you, fine and thank you.\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "🔍 Analyzing: 'How are you, fine and thank you.'\n",
      "🎯 Predicted next word: 'think'\n",
      "\n",
      "📊 Top 10 candidates:\n",
      "   1. have            (0.1389)\n",
      "   2. are             (0.0899)\n",
      "   3. and             (0.0662)\n",
      "   4. unk             (0.0654)\n",
      "   5. re              (0.0547)\n",
      "   6. were            (0.0524)\n",
      "   7. to              (0.0382)\n",
      "   8. was             (0.0378)\n",
      "   9. can             (0.0375)\n",
      "  10. had             (0.0271)\n",
      "\n",
      "📝 Complete sentence: 'How are you, fine and thank you. think'\n"
     ]
    }
   ],
   "source": [
    "# Test the trained model\n",
    "\n",
    "# Text Generation and Next Word Prediction\n",
    "\n",
    "import torch\n",
    "import torch.nn.functional as F\n",
    "\n",
    "def predict_next_word(model, input_text, vocab, idx_to_word, device, temperature=1.0, top_k=None):\n",
    "    \"\"\"\n",
    "    Predict the next word given an input text\n",
    "    \n",
    "    Args:\n",
    "        model: Trained GRU model\n",
    "        input_text: Input sentence as string\n",
    "        vocab: Vocabulary dictionary\n",
    "        idx_to_word: Index to word mapping\n",
    "        device: Device to run inference on\n",
    "        temperature: Sampling temperature (higher = more random)\n",
    "        top_k: If specified, only sample from top k most likely tokens\n",
    "    \n",
    "    Returns:\n",
    "        predicted_word: The predicted next word\n",
    "        probabilities: Top 10 word probabilities\n",
    "    \"\"\"\n",
    "    model.eval()\n",
    "    \n",
    "    with torch.no_grad():\n",
    "        # Tokenize input text\n",
    "        tokens = basic_tokenize(input_text)\n",
    "        if len(tokens) == 0:\n",
    "            return \"<unk>\", []\n",
    "        \n",
    "        # Convert to indices\n",
    "        indices = [vocab.get(token, vocab['<unk>']) for token in tokens]\n",
    "        \n",
    "        # Pad or truncate to sequence length (50)\n",
    "        sequence_length = 50\n",
    "        if len(indices) < sequence_length:\n",
    "            # Pad with <pad> tokens at the beginning\n",
    "            indices = [vocab['<pad>']] * (sequence_length - len(indices)) + indices\n",
    "        else:\n",
    "            # Take the last 50 tokens\n",
    "            indices = indices[-sequence_length:]\n",
    "        \n",
    "        # Convert to tensor\n",
    "        input_tensor = torch.tensor([indices], dtype=torch.long).to(device)  # [1, seq_len]\n",
    "        \n",
    "        # Forward pass\n",
    "        logits, hidden = model(input_tensor)\n",
    "        \n",
    "        # Get logits for the last token\n",
    "        last_logits = logits[0, -1, :]  # [vocab_size]\n",
    "        \n",
    "        # Apply temperature\n",
    "        if temperature != 1.0:\n",
    "            last_logits = last_logits / temperature\n",
    "        \n",
    "        # Apply top-k filtering if specified\n",
    "        if top_k is not None:\n",
    "            top_k = min(top_k, last_logits.size(-1))\n",
    "            top_k_logits, top_k_indices = torch.topk(last_logits, top_k)\n",
    "            # Set all other logits to negative infinity\n",
    "            filtered_logits = torch.full_like(last_logits, float('-inf'))\n",
    "            filtered_logits[top_k_indices] = top_k_logits\n",
    "            last_logits = filtered_logits\n",
    "        \n",
    "        # Convert to probabilities\n",
    "        probabilities = F.softmax(last_logits, dim=-1)\n",
    "        \n",
    "        # Get top 10 predictions for display\n",
    "        top_probs, top_indices = torch.topk(probabilities, 10)\n",
    "        top_words = [(idx_to_word[idx.item()], prob.item()) for idx, prob in zip(top_indices, top_probs)]\n",
    "        \n",
    "        # Sample from the distribution\n",
    "        # Filter out special tokens from probabilities before sampling\n",
    "        special_token_indices = [vocab['<unk>'], vocab['<pad>']]\n",
    "        for idx in special_token_indices:\n",
    "            probabilities[idx] = 0.0\n",
    "        # Renormalize\n",
    "        probabilities = probabilities / probabilities.sum()\n",
    "        # Then sample normally\n",
    "        predicted_idx = torch.multinomial(probabilities, 1).item()\n",
    "        predicted_word = idx_to_word[predicted_idx]\n",
    "\n",
    "        return predicted_word, top_words\n",
    "\n",
    "def generate_text(model, seed_text, vocab, idx_to_word, device, num_words=10, temperature=1.0, top_k=50):\n",
    "    \"\"\"\n",
    "    Generate multiple words continuing from seed text\n",
    "    \n",
    "    Args:\n",
    "        model: Trained GRU model\n",
    "        seed_text: Starting text\n",
    "        vocab: Vocabulary dictionary\n",
    "        idx_to_word: Index to word mapping\n",
    "        device: Device to run inference on\n",
    "        num_words: Number of words to generate\n",
    "        temperature: Sampling temperature\n",
    "        top_k: Top-k sampling parameter\n",
    "    \n",
    "    Returns:\n",
    "        generated_text: Complete generated text\n",
    "    \"\"\"\n",
    "    model.eval()\n",
    "    \n",
    "    current_text = seed_text\n",
    "    generated_words = []\n",
    "    \n",
    "    print(f\"Seed text: '{seed_text}'\")\n",
    "    print(\"Generating words:\")\n",
    "    \n",
    "    for i in range(num_words):\n",
    "        predicted_word, top_words = predict_next_word(\n",
    "            model, current_text, vocab, idx_to_word, device, temperature, top_k\n",
    "        )\n",
    "        \n",
    "        # Skip special tokens\n",
    "        if predicted_word in ['<unk>', '<pad>']:\n",
    "            predicted_word = top_words[1][0] if len(top_words) > 1 else \"the\"\n",
    "        \n",
    "        generated_words.append(predicted_word)\n",
    "        current_text += \" \" + predicted_word\n",
    "        \n",
    "        print(f\"  {i+1}. {predicted_word} (top candidates: {[w[0] for w in top_words[:3]]})\")\n",
    "    \n",
    "    generated_text = seed_text + \" \" + \" \".join(generated_words)\n",
    "    return generated_text\n",
    "\n",
    "def interactive_prediction(model, vocab, idx_to_word, device):\n",
    "    \"\"\"\n",
    "    Interactive mode for testing the model\n",
    "    \"\"\"\n",
    "    print(\"\\n🤖 Interactive Text Prediction Mode\")\n",
    "    print(\"Enter a sentence and I'll predict the next word!\")\n",
    "    print(\"Type 'quit' to exit, 'generate' to generate multiple words\")\n",
    "    print(\"-\" * 60)\n",
    "    \n",
    "    while True:\n",
    "        user_input = input(\"\\nEnter text: \").strip()\n",
    "        \n",
    "        if user_input.lower() == 'quit':\n",
    "            print(\"Goodbye! 👋\")\n",
    "            break\n",
    "        \n",
    "        if user_input.lower() == 'generate':\n",
    "            seed_text = input(\"Enter seed text for generation: \").strip()\n",
    "            if seed_text:\n",
    "                num_words = int(input(\"How many words to generate? (default 10): \") or \"10\")\n",
    "                temperature = float(input(\"Temperature (0.1-2.0, default 1.0): \") or \"1.0\")\n",
    "                \n",
    "                print(f\"\\n🎯 Generating {num_words} words...\")\n",
    "                generated = generate_text(model, seed_text, vocab, idx_to_word, device, \n",
    "                                        num_words=num_words, temperature=temperature, top_k=50)\n",
    "                print(f\"\\n📝 Complete text: '{generated}'\")\n",
    "            continue\n",
    "        \n",
    "        if user_input:\n",
    "            print(f\"\\n🔍 Analyzing: '{user_input}'\")\n",
    "            \n",
    "            # Predict next word\n",
    "            predicted_word, top_words = predict_next_word(\n",
    "                model, user_input, vocab, idx_to_word, device, temperature=1.0, top_k=50\n",
    "            )\n",
    "            \n",
    "            print(f\"🎯 Predicted next word: '{predicted_word}'\")\n",
    "            print(f\"\\n📊 Top 10 candidates:\")\n",
    "            for i, (word, prob) in enumerate(top_words, 1):\n",
    "                print(f\"  {i:2d}. {word:<15} ({prob:.4f})\")\n",
    "            \n",
    "            # Show the complete sentence\n",
    "            complete_sentence = user_input + \" \" + predicted_word\n",
    "            print(f\"\\n📝 Complete sentence: '{complete_sentence}'\")\n",
    "\n",
    "# Test the model with some examples\n",
    "print(\"🧪 Testing the trained GRU model...\")\n",
    "\n",
    "# Example sentences to test\n",
    "test_sentences = [\n",
    "    \"The cat sat on the\",\n",
    "    \"I love to eat\",\n",
    "    \"The weather today is\",\n",
    "    \"Machine learning is\",\n",
    "    \"In the future we will\",\n",
    "    \"The president of the United\",\n",
    "    \"Scientists have discovered a new\",\n",
    "    \"The book was very\"\n",
    "]\n",
    "\n",
    "print(\"\\n📋 Testing with example sentences:\")\n",
    "print(\"=\" * 60)\n",
    "\n",
    "for i, sentence in enumerate(test_sentences, 1):\n",
    "    print(f\"\\n{i}. Input: '{sentence}'\")\n",
    "    \n",
    "    predicted_word, top_words = predict_next_word(\n",
    "        model, sentence, vocab, idx_to_word, device, temperature=0.8, top_k=50\n",
    "    )\n",
    "    \n",
    "    print(f\"   Predicted: '{predicted_word}'\")\n",
    "    print(f\"   Top 3: {[w[0] for w in top_words[:3]]}\")\n",
    "    print(f\"   Complete: '{sentence} {predicted_word}'\")\n",
    "\n",
    "# Start interactive mode\n",
    "interactive_prediction(model, vocab, idx_to_word, device)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "archer",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
